關於spring security ouath 中/oauth/authorize請求
AuthorizationEndpoint
首先進行clientDetail信息校驗,查看是否有權限不經過確認頁面直接跳轉,如果爲真,則不需要確認頁面直接跳轉,否則跳轉到確認頁面,點擊授權,才能重定向
具體確認頁面請看WhitelabelApprovalEndpoint類
@RequestMapping(value = "/oauth/authorize")
public ModelAndView authorize(Map<String, Object> model, @RequestParam Map<String, String> parameters,
SessionStatus sessionStatus, Principal principal) {
AuthorizationRequest authorizationRequest = getOAuth2RequestFactory().createAuthorizationRequest(parameters);
Set<String> responseTypes = authorizationRequest.getResponseTypes();
if (!responseTypes.contains("token") && !responseTypes.contains("code")) {
throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes);
}
if (authorizationRequest.getClientId() == null) {
throw new InvalidClientException("A client id must be provided");
}
try {
if (!(principal instanceof Authentication) || !((Authentication) principal).isAuthenticated()) {
throw new InsufficientAuthenticationException(
"User must be authenticated with Spring Security before authorization can be completed.");
}
// 獲取clientDetails信息,及client_id,client_scret...
ClientDetails client = getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId());
String redirectUriParameter = authorizationRequest.getRequestParameters().get(OAuth2Utils.REDIRECT_URI);
String resolvedRedirect = redirectResolver.resolveRedirect(redirectUriParameter, client);
if (!StringUtils.hasText(resolvedRedirect)) {
throw new RedirectMismatchException(
"A redirectUri must be either supplied or preconfigured in the ClientDetails");
}
authorizationRequest.setRedirectUri(resolvedRedirect);
oauth2RequestValidator.validateScope(authorizationRequest, client);
// 否則跳轉到確認頁面,確認頁面WhitelabelApprovalEndpoint,
authorizationRequest = userApprovalHandler.checkForPreApproval(authorizationRequest,
(Authentication) principal);
boolean approved = userApprovalHandler.isApproved(authorizationRequest, (Authentication) principal);
authorizationRequest.setApproved(approved);
if (authorizationRequest.isApproved()) {
if (responseTypes.contains("token")) {
return getImplicitGrantResponse(authorizationRequest);
}
if (responseTypes.contains("code")) {
return new ModelAndView(getAuthorizationCodeResponse(authorizationRequest,
(Authentication) principal));
}
}
model.put(AUTHORIZATION_REQUEST_ATTR_NAME, authorizationRequest);
model.put(ORIGINAL_AUTHORIZATION_REQUEST_ATTR_NAME, unmodifiableMap(authorizationRequest));
return getUserApprovalPageResponse(model, authorizationRequest, (Authentication) principal);
}
catch (RuntimeException e) {
sessionStatus.setComplete();
throw e;
}
}
checkForPreApproval
是否不經過確認頁面具體邏輯代碼
1、查詢clientDetail中存在的scope是否包含請求中的scope,包含則進行處理(如在JdbcApprovalStore中則會刷新approval然後新增approval信息),返回approval爲true
2、查詢approval列表,和請求中的scope做對照
public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest,
Authentication userAuthentication) {
String clientId = authorizationRequest.getClientId();
Collection<String> requestedScopes = authorizationRequest.getScope();
Set<String> approvedScopes = new HashSet<String>();
Set<String> validUserApprovedScopes = new HashSet<String>();
if (clientDetailsService != null) {
try {
// 查詢clientDetail中存在的scope是否包含請求中的scope
ClientDetails client = clientDetailsService.loadClientByClientId(clientId);
for (String scope : requestedScopes) {
if (client.isAutoApprove(scope)) {
approvedScopes.add(scope);
}
}
if (approvedScopes.containsAll(requestedScopes)) {
// gh-877 - if all scopes are auto approved, approvals still need to be added to the approval store.
Set<Approval> approvals = new HashSet<Approval>();
Date expiry = computeExpiry();
for (String approvedScope : approvedScopes) {
approvals.add(new Approval(userAuthentication.getName(), authorizationRequest.getClientId(),
approvedScope, expiry, ApprovalStatus.APPROVED));
}
approvalStore.addApprovals(approvals);
authorizationRequest.setApproved(true);
return authorizationRequest;
}
}
catch (ClientRegistrationException e) {
logger.warn("Client registration problem prevent autoapproval check for client=" + clientId);
}
}
if (logger.isDebugEnabled()) {
StringBuilder builder = new StringBuilder("Looking up user approved authorizations for ");
builder.append("client_id=" + clientId);
builder.append(" and username=" + userAuthentication.getName());
logger.debug(builder.toString());
}
// 查詢approval列表,和請求中的scope做對照
// Find the stored approvals for that user and client
Collection<Approval> userApprovals = approvalStore.getApprovals(userAuthentication.getName(), clientId);
// Look at the scopes and see if they have expired
Date today = new Date();
for (Approval approval : userApprovals) {
if (approval.getExpiresAt().after(today)) {
if (approval.getStatus() == ApprovalStatus.APPROVED) {
validUserApprovedScopes.add(approval.getScope());
approvedScopes.add(approval.getScope());
}
}
}
if (logger.isDebugEnabled()) {
logger.debug("Valid user approved/denied scopes are " + validUserApprovedScopes);
}
// If the requested scopes have already been acted upon by the user,
// this request is approved
if (validUserApprovedScopes.containsAll(requestedScopes)) {
approvedScopes.retainAll(requestedScopes);
// Set only the scopes that have been approved by the user
authorizationRequest.setScope(approvedScopes);
authorizationRequest.setApproved(true);
}
return authorizationRequest;
}