CongressService & MomentaryService
This commit is contained in:
@@ -17,28 +17,36 @@
|
||||
|
||||
package org.maxkey.authz.oauth2.provider.approval.endpoint;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.maxkey.authn.annotation.CurrentUser;
|
||||
import org.maxkey.authn.web.AuthorizationUtils;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
import org.maxkey.authz.oauth2.provider.AuthorizationRequest;
|
||||
import org.maxkey.authz.oauth2.provider.ClientDetailsService;
|
||||
import org.maxkey.authz.oauth2.provider.approval.Approval;
|
||||
import org.maxkey.authz.oauth2.provider.approval.Approval.ApprovalStatus;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.entity.Message;
|
||||
import org.maxkey.entity.UserInfo;
|
||||
import org.maxkey.entity.apps.Apps;
|
||||
import org.maxkey.entity.apps.oauth2.provider.ClientDetails;
|
||||
import org.maxkey.authz.oauth2.provider.approval.ApprovalStore;
|
||||
import org.maxkey.persistence.MomentaryService;
|
||||
import org.maxkey.persistence.service.AppsService;
|
||||
import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.util.StringUtils;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
@@ -48,7 +56,6 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
* @author Ryan Heaton
|
||||
*/
|
||||
@Controller
|
||||
@SessionAttributes("authorizationRequest")
|
||||
public class OAuth20AccessConfirmationEndpoint {
|
||||
static final Logger _logger = LoggerFactory.getLogger(OAuth20AccessConfirmationEndpoint.class);
|
||||
|
||||
@@ -68,6 +75,12 @@ public class OAuth20AccessConfirmationEndpoint {
|
||||
@Qualifier("oauth20UserApprovalHandler")
|
||||
OAuth20UserApprovalHandler oauth20UserApprovalHandler;
|
||||
|
||||
@Autowired
|
||||
protected MomentaryService momentaryService;
|
||||
|
||||
@Autowired
|
||||
protected ApplicationConfig applicationConfig;
|
||||
|
||||
/**
|
||||
* getAccessConfirmation.
|
||||
* @param model Map
|
||||
@@ -76,20 +89,15 @@ public class OAuth20AccessConfirmationEndpoint {
|
||||
*/
|
||||
@RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_APPROVAL_CONFIRM)
|
||||
public ModelAndView getAccessConfirmation(
|
||||
@RequestParam Map<String, Object> model) {
|
||||
@RequestParam Map<String, Object> model,@CurrentUser UserInfo currentUser) {
|
||||
try {
|
||||
model.remove("authorizationRequest");
|
||||
|
||||
// Map<String, Object> model
|
||||
AuthorizationRequest clientAuth =
|
||||
(AuthorizationRequest) WebContext.getAttribute("authorizationRequest");
|
||||
(AuthorizationRequest) momentaryService.get(currentUser.getOnlineTicket(), "authorizationRequest");
|
||||
ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId(),true);
|
||||
Apps app = (Apps)WebContext.getAttribute(WebConstants.AUTHORIZE_SIGN_ON_APP);
|
||||
WebContext.setAttribute(app.getId(), app.getIcon());
|
||||
|
||||
model.put("oauth_approval", WebContext.genId());
|
||||
model.put("auth_request", clientAuth);
|
||||
model.put("client", client);
|
||||
model.put("app", app);
|
||||
model.put("oauth_version", "oauth 2.0");
|
||||
Map<String, String> scopes = new LinkedHashMap<String, String>();
|
||||
for (String scope : clientAuth.getScope()) {
|
||||
@@ -117,9 +125,60 @@ public class OAuth20AccessConfirmationEndpoint {
|
||||
for (Object key : model.keySet()) {
|
||||
_logger.trace("key " + key +"=" + model.get(key));
|
||||
}
|
||||
model.put("authorizeApproveUri", applicationConfig.getFrontendUri()+"/#/authz/oauth2approve");
|
||||
|
||||
modelAndView.addObject("model", model);
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
@RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_APPROVAL_CONFIRM+"/get/{oauth_approval}")
|
||||
public ResponseEntity<?> getAccess(
|
||||
@PathVariable("oauth_approval") String oauth_approval,
|
||||
@CurrentUser UserInfo currentUser) {
|
||||
Map<String, Object> model = new HashMap<String, Object>();
|
||||
if(StringUtils.isNotBlank(oauth_approval)) {
|
||||
try {
|
||||
AuthorizationRequest clientAuth =
|
||||
(AuthorizationRequest) momentaryService.get(currentUser.getOnlineTicket(), "authorizationRequest");
|
||||
ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId(),true);
|
||||
|
||||
Apps app = appsService.get(client.getClientId(),true);
|
||||
app.transIconBase64();
|
||||
|
||||
model.put("auth_request", clientAuth);
|
||||
model.put("client", client);
|
||||
model.put("clientId", clientAuth.getClientId());
|
||||
model.put("appName", app.getName());
|
||||
model.put("iconBase64", app.getIconBase64());
|
||||
model.put("oauth_version", "oauth 2.0");
|
||||
Map<String, String> scopes = new LinkedHashMap<String, String>();
|
||||
for (String scope : clientAuth.getScope()) {
|
||||
scopes.put(OAuth2Constants.PARAMETER.SCOPE_PREFIX + scope, "false");
|
||||
}
|
||||
String principal = AuthorizationUtils.getPrincipal().getUsername();
|
||||
for (Approval approval : approvalStore.getApprovals(principal, client.getClientId())) {
|
||||
if (clientAuth.getScope().contains(approval.getScope())) {
|
||||
scopes.put(OAuth2Constants.PARAMETER.SCOPE_PREFIX + approval.getScope(),
|
||||
approval.getStatus() == ApprovalStatus.APPROVED ? "true" : "false");
|
||||
}
|
||||
}
|
||||
|
||||
model.put("scopes", scopes);
|
||||
|
||||
if(!model.containsKey(OAuth2Constants.PARAMETER.APPROVAL_PROMPT)) {
|
||||
model.put(OAuth2Constants.PARAMETER.APPROVAL_PROMPT, client.getApprovalPrompt());
|
||||
}
|
||||
}catch(Exception e) {
|
||||
_logger.debug("OAuth Access Confirmation process error." ,e);
|
||||
}
|
||||
|
||||
_logger.trace("Confirmation details ");
|
||||
for (Object key : model.keySet()) {
|
||||
_logger.trace("key " + key +"=" + model.get(key));
|
||||
}
|
||||
}
|
||||
return new Message<Map<String, Object>>(model).buildResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* handleError.
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.maxkey.authz.oauth2.provider.refresh.RefreshTokenGranter;
|
||||
import org.maxkey.authz.oauth2.provider.request.DefaultOAuth2RequestFactory;
|
||||
import org.maxkey.authz.oauth2.provider.token.AuthorizationServerTokenServices;
|
||||
import org.maxkey.configuration.ApplicationConfig;
|
||||
import org.maxkey.persistence.MomentaryService;
|
||||
import org.maxkey.persistence.service.AppsService;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -84,6 +85,9 @@ public class AbstractEndpoint implements InitializingBean {
|
||||
@Qualifier("applicationConfig")
|
||||
protected ApplicationConfig applicationConfig;
|
||||
|
||||
@Autowired
|
||||
protected MomentaryService momentaryService;
|
||||
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (tokenGranter == null) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.mybatis.jpa.util.JpaWebContext;
|
||||
import org.maxkey.authn.annotation.CurrentUser;
|
||||
import org.maxkey.authn.web.AuthorizationUtils;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2AccessToken;
|
||||
import org.maxkey.authz.oauth2.common.OAuth2Constants;
|
||||
@@ -48,6 +49,8 @@ import org.maxkey.authz.oauth2.provider.request.DefaultOAuth2RequestValidator;
|
||||
import org.maxkey.constants.ContentType;
|
||||
import org.maxkey.crypto.jose.keystore.JWKSetKeyStore;
|
||||
import org.maxkey.util.HttpEncoder;
|
||||
import org.maxkey.entity.Message;
|
||||
import org.maxkey.entity.UserInfo;
|
||||
import org.maxkey.entity.apps.Apps;
|
||||
import org.maxkey.entity.apps.oauth2.provider.ClientDetails;
|
||||
import org.maxkey.web.HttpRequestAdapter;
|
||||
@@ -55,6 +58,7 @@ import org.maxkey.web.WebConstants;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.InsufficientAuthenticationException;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
@@ -65,7 +69,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
import org.springframework.web.bind.support.SessionStatus;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.View;
|
||||
@@ -96,7 +99,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
*/
|
||||
@Tag(name = "2-1-OAuth v2.0 API文档模块")
|
||||
@Controller
|
||||
@SessionAttributes("authorizationRequest")
|
||||
public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
final static Logger _logger = LoggerFactory.getLogger(AuthorizationEndpoint.class);
|
||||
|
||||
@@ -120,7 +122,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
}
|
||||
|
||||
@Operation(summary = "OAuth 2.0 认证接口", description = "传递参数应用ID,自动完成跳转认证拼接",method="GET")
|
||||
@RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/{id}")
|
||||
@RequestMapping(value = {OAuth2Constants.ENDPOINT.ENDPOINT_BASE + "/{id}"},method = RequestMethod.GET)
|
||||
public ModelAndView authorize(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
@@ -152,6 +154,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
public ModelAndView authorize(
|
||||
Map<String, Object> model,
|
||||
@RequestParam Map<String, String> parameters,
|
||||
@CurrentUser UserInfo currentUser,
|
||||
SessionStatus sessionStatus) {
|
||||
|
||||
Principal principal=(Principal)AuthorizationUtils.getAuthentication();
|
||||
@@ -207,7 +210,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
// Validation is all done, so we can check for auto approval...
|
||||
if (authorizationRequest.isApproved()) {
|
||||
if (responseTypes.contains(OAuth2Constants.PARAMETER.TOKEN)) {
|
||||
return getImplicitGrantResponse(authorizationRequest);
|
||||
return new ModelAndView(getImplicitGrantResponse(authorizationRequest));
|
||||
}
|
||||
if (responseTypes.contains(OAuth2Constants.PARAMETER.CODE)) {
|
||||
return new ModelAndView(getAuthorizationCodeResponse(authorizationRequest,
|
||||
@@ -224,8 +227,8 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
// Place auth request into the model so that it is stored in the session
|
||||
// for approveOrDeny to use. That way we make sure that auth request comes from the session,
|
||||
// so any auth request parameters passed to approveOrDeny will be ignored and retrieved from the session.
|
||||
model.put("authorizationRequest", authorizationRequest);
|
||||
|
||||
momentaryService.put(currentUser.getOnlineTicket(), "authorizationRequest", authorizationRequest);
|
||||
|
||||
return getUserApprovalPageResponse(model, authorizationRequest, (Authentication) principal);
|
||||
|
||||
}
|
||||
@@ -237,22 +240,22 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
}
|
||||
|
||||
//approval must post
|
||||
@RequestMapping(value = {OAuth2Constants.ENDPOINT.ENDPOINT_AUTHORIZE},
|
||||
@RequestMapping(value = {OAuth2Constants.ENDPOINT.ENDPOINT_AUTHORIZE+"/approval"},
|
||||
params = OAuth2Constants.PARAMETER.USER_OAUTH_APPROVAL,
|
||||
method = RequestMethod.POST)
|
||||
public View approveOrDeny(
|
||||
public ResponseEntity<?> authorizeApproveOrDeny(
|
||||
@RequestParam Map<String, String> approvalParameters,
|
||||
Map<String, ?> model,
|
||||
@CurrentUser UserInfo currentUser,
|
||||
SessionStatus sessionStatus) {
|
||||
|
||||
Principal principal=(Principal)AuthorizationUtils.getAuthentication();
|
||||
Principal principal = (Principal)AuthorizationUtils.getAuthentication();
|
||||
if (!(principal instanceof Authentication)) {
|
||||
sessionStatus.setComplete();
|
||||
throw new InsufficientAuthenticationException(
|
||||
"User must be authenticated with Spring Security before authorizing an access token.");
|
||||
}
|
||||
|
||||
AuthorizationRequest authorizationRequest = (AuthorizationRequest) model.get("authorizationRequest");
|
||||
AuthorizationRequest authorizationRequest = (AuthorizationRequest) momentaryService.get(currentUser.getOnlineTicket(), "authorizationRequest");
|
||||
|
||||
if (authorizationRequest == null) {
|
||||
sessionStatus.setComplete();
|
||||
@@ -274,20 +277,22 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
}
|
||||
|
||||
if (!authorizationRequest.isApproved()) {
|
||||
return new RedirectView(
|
||||
getUnsuccessfulRedirect(
|
||||
authorizationRequest,
|
||||
new UserDeniedAuthorizationException("User denied access"),
|
||||
responseTypes.contains(OAuth2Constants.PARAMETER.TOKEN)
|
||||
),
|
||||
false, true, false);
|
||||
return new Message< Object>(Message.FAIL,(Object)
|
||||
getUnsuccessfulRedirect(
|
||||
authorizationRequest,
|
||||
new UserDeniedAuthorizationException("User denied access"),
|
||||
responseTypes.contains(OAuth2Constants.PARAMETER.TOKEN)
|
||||
)
|
||||
).buildResponse();
|
||||
}
|
||||
|
||||
if (responseTypes.contains(OAuth2Constants.PARAMETER.TOKEN)) {
|
||||
return getImplicitGrantResponse(authorizationRequest).getView();
|
||||
return new Message< Object>((Object)
|
||||
getImplicitGrantResponse(authorizationRequest)).buildResponse();
|
||||
}
|
||||
|
||||
return getAuthorizationCodeResponse(authorizationRequest, (Authentication) principal);
|
||||
return new Message< Object>((Object)
|
||||
getAuthorizationCodeResponse(authorizationRequest, (Authentication) principal)).buildResponse();
|
||||
}
|
||||
finally {
|
||||
sessionStatus.setComplete();
|
||||
@@ -340,7 +345,7 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
}
|
||||
|
||||
// We can grant a token and return it with implicit approval.
|
||||
private ModelAndView getImplicitGrantResponse(AuthorizationRequest authorizationRequest) {
|
||||
private String getImplicitGrantResponse(AuthorizationRequest authorizationRequest) {
|
||||
try {
|
||||
TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(authorizationRequest, "implicit");
|
||||
OAuth2Request storedOAuth2Request = getOAuth2RequestFactory().createOAuth2Request(authorizationRequest);
|
||||
@@ -349,24 +354,10 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
if (accessToken == null) {
|
||||
throw new UnsupportedResponseTypeException("Unsupported response type: token");
|
||||
}
|
||||
return new ModelAndView(
|
||||
new RedirectView(
|
||||
appendAccessToken(authorizationRequest, accessToken),
|
||||
false,
|
||||
true,
|
||||
false
|
||||
)
|
||||
);
|
||||
return appendAccessToken(authorizationRequest, accessToken);
|
||||
}
|
||||
catch (OAuth2Exception e) {
|
||||
return new ModelAndView(
|
||||
new RedirectView(
|
||||
getUnsuccessfulRedirect(authorizationRequest, e, true),
|
||||
false,
|
||||
true,
|
||||
false
|
||||
)
|
||||
);
|
||||
return getUnsuccessfulRedirect(authorizationRequest, e, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,17 +373,17 @@ public class AuthorizationEndpoint extends AbstractEndpoint {
|
||||
}
|
||||
|
||||
// Authorization Code Response
|
||||
private View getAuthorizationCodeResponse(AuthorizationRequest authorizationRequest, Authentication authUser) {
|
||||
private String getAuthorizationCodeResponse(AuthorizationRequest authorizationRequest, Authentication authUser) {
|
||||
try {
|
||||
String successfulRedirect = getSuccessfulRedirect(
|
||||
authorizationRequest,
|
||||
generateCode(authorizationRequest, authUser)
|
||||
);
|
||||
_logger.debug("successfulRedirect " + successfulRedirect);
|
||||
return new RedirectView(successfulRedirect, false, true, false);
|
||||
return successfulRedirect;
|
||||
}
|
||||
catch (OAuth2Exception e) {
|
||||
return new RedirectView(getUnsuccessfulRedirect(authorizationRequest, e, false), false, true, false);
|
||||
return getUnsuccessfulRedirect(authorizationRequest, e, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user