|
|
|
@ -3,10 +3,11 @@ package org.mitre.openid.connect.server;
|
|
|
|
|
import java.io.UnsupportedEncodingException; |
|
|
|
|
import java.net.URLEncoder; |
|
|
|
|
import java.security.Principal; |
|
|
|
|
import java.util.Arrays; |
|
|
|
|
import java.util.Collection; |
|
|
|
|
import java.util.Date; |
|
|
|
|
import java.util.HashMap; |
|
|
|
|
import java.util.HashSet; |
|
|
|
|
import java.util.Map; |
|
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
|
|
import org.mitre.jwt.model.Jwt; |
|
|
|
|
import org.mitre.jwt.model.JwtClaims; |
|
|
|
@ -20,7 +21,6 @@ import org.springframework.security.oauth2.common.exceptions.InvalidGrantExcepti
|
|
|
|
|
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; |
|
|
|
|
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException; |
|
|
|
|
import org.springframework.security.oauth2.common.exceptions.UnsupportedGrantTypeException; |
|
|
|
|
import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException; |
|
|
|
|
import org.springframework.security.oauth2.provider.AuthorizationRequest; |
|
|
|
|
import org.springframework.security.oauth2.provider.ClientDetailsService; |
|
|
|
|
import org.springframework.security.oauth2.provider.approval.DefaultUserApprovalHandler; |
|
|
|
@ -33,9 +33,7 @@ import org.springframework.security.oauth2.provider.endpoint.DefaultRedirectReso
|
|
|
|
|
import org.springframework.security.oauth2.provider.endpoint.RedirectResolver; |
|
|
|
|
import org.springframework.stereotype.Controller; |
|
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
|
import org.springframework.web.bind.annotation.ModelAttribute; |
|
|
|
|
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.SessionAttributes; |
|
|
|
|
import org.springframework.web.bind.support.SessionStatus; |
|
|
|
@ -59,22 +57,20 @@ public class AuthorizationEndpointRequestObject extends AbstractEndpoint impleme
|
|
|
|
|
private String userApprovalPage = "forward:/oauth/confirm_access"; |
|
|
|
|
|
|
|
|
|
@RequestMapping(params = "response_type") |
|
|
|
|
public ModelAndView getRequest(Map<String, Object> model, @RequestParam("request") String jwtString, |
|
|
|
|
public ModelAndView authorizeRequestObject(Map<String, Object> model, @RequestParam("request") String jwtString, |
|
|
|
|
@RequestParam Map<String, String> parameters, SessionStatus sessionStatus, Principal principal) { |
|
|
|
|
|
|
|
|
|
Jwt jwt = Jwt.parse(jwtString); |
|
|
|
|
JwtClaims claims = jwt.getClaims(); |
|
|
|
|
|
|
|
|
|
String clientId = claims.getClaimAsString("client_id"); |
|
|
|
|
String[] scopeString = new String[]{claims.getClaimAsString("scope")}; |
|
|
|
|
Collection<String> scope = new HashSet<String>(Arrays.asList(scopeString)); |
|
|
|
|
|
|
|
|
|
// Manually initialize auth request instead of using @ModelAttribute
|
|
|
|
|
// to make sure it comes from request instead of the session
|
|
|
|
|
|
|
|
|
|
Map<String, String> jwtParameters = new HashMap<String, String>(); |
|
|
|
|
|
|
|
|
|
jwtParameters.put("client_id", claims.getClaimAsString("client_id")); |
|
|
|
|
jwtParameters.put("redirect_uri", claims.getClaimAsString("redirect_uri")); |
|
|
|
|
jwtParameters.put("scope", claims.getClaimAsString("scope")); |
|
|
|
|
|
|
|
|
|
AuthorizationRequest authorizationRequest = new AuthorizationRequest(jwtParameters); |
|
|
|
|
AuthorizationRequest authorizationRequest = new AuthorizationRequest(parameters, null, clientId, scope); |
|
|
|
|
|
|
|
|
|
if (claims.getClaim("client_id") == null) { |
|
|
|
|
sessionStatus.setComplete(); |
|
|
|
@ -87,7 +83,7 @@ public class AuthorizationEndpointRequestObject extends AbstractEndpoint impleme
|
|
|
|
|
"User must be authenticated with Spring Security before authorization can be completed."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!claims.getClaim("response_type").equals("token") && !claims.getClaim("response_type").equals("code")) { |
|
|
|
|
if (!authorizationRequest.getResponseTypes().contains("token") && !authorizationRequest.getResponseTypes().contains("code")) { |
|
|
|
|
throw new UnsupportedGrantTypeException("Unsupported response types: " + claims.getClaim("response_type")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -118,45 +114,6 @@ public class AuthorizationEndpointRequestObject extends AbstractEndpoint impleme
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@RequestMapping(method = RequestMethod.POST, params = AuthorizationRequest.USER_OAUTH_APPROVAL) |
|
|
|
|
public View approveOrDeny(@RequestParam Map<String, String> approvalParameters, |
|
|
|
|
@ModelAttribute AuthorizationRequest authorizationRequest, SessionStatus sessionStatus, Principal principal) { |
|
|
|
|
|
|
|
|
|
if (authorizationRequest.getClientId() == null) { |
|
|
|
|
sessionStatus.setComplete(); |
|
|
|
|
throw new InvalidClientException("A client_id must be supplied."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!(principal instanceof Authentication)) { |
|
|
|
|
sessionStatus.setComplete(); |
|
|
|
|
throw new InsufficientAuthenticationException( |
|
|
|
|
"User must be authenticated with Spring Security before authorizing an access token."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
Set<String> responseTypes = authorizationRequest.getResponseTypes(); |
|
|
|
|
|
|
|
|
|
authorizationRequest = authorizationRequest.addApprovalParameters(approvalParameters); |
|
|
|
|
authorizationRequest = resolveRedirectUriAndCheckApproval(authorizationRequest, (Authentication) principal); |
|
|
|
|
|
|
|
|
|
if (!authorizationRequest.isApproved()) { |
|
|
|
|
return new RedirectView(getUnsuccessfulRedirect(authorizationRequest, |
|
|
|
|
new UserDeniedAuthorizationException("User denied access"), responseTypes.contains("token")), |
|
|
|
|
false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (responseTypes.contains("token")) { |
|
|
|
|
return getImplicitGrantResponse(authorizationRequest).getView(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return getAuthorizationCodeResponse(authorizationRequest, (Authentication) principal); |
|
|
|
|
} |
|
|
|
|
finally { |
|
|
|
|
sessionStatus.setComplete(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// TODO: Remove when possible
|
|
|
|
|
// COPIED FROM SECOAUTH AuthorizationEndpoint
|
|
|
|
|