// 要不要PreApproval?? @Override public AuthorizationRequest checkForPreApproval( AuthorizationRequest authorizationRequest, Authentication userAuthentication) { boolean approved = false; String clientId = authorizationRequest.getClientId(); Set<String> scopes = authorizationRequest.getScope(); OAuth2Request storedOAuth2Request = requestFactory.createOAuth2Request(authorizationRequest); OAuth2Authentication authentication = new OAuth2Authentication(storedOAuth2Request, userAuthentication); if (logger.isDebugEnabled()) { StringBuilder builder = new StringBuilder("Looking up existing token for "); builder.append("client_id=" + clientId); builder.append(", scope=" + scopes); builder.append(" and username="******"Existing access token=" + accessToken); if (accessToken != null && !accessToken.isExpired()) { logger.debug("User already approved with token=" + accessToken); approved = true; } else { logger.debug("Checking explicit approval"); approved = userAuthentication.isAuthenticated() && approved; } authorizationRequest.setApproved(approved); return authorizationRequest; }
/** * Basic implementation just requires the authorization request to be explicitly approved and the * user to be authenticated. * * @param authorizationRequest The authorization request. * @param userAuthentication the current user authentication * @return Whether the specified request has been approved by the current user. */ public boolean isApproved( AuthorizationRequest authorizationRequest, Authentication userAuthentication) { String flag = authorizationRequest.getApprovalParameters().get(approvalParameter); boolean approved = flag != null && flag.toLowerCase().equals("true"); OAuth2Authentication authentication = new OAuth2Authentication(authorizationRequest, userAuthentication); if (logger.isDebugEnabled()) { StringBuilder builder = new StringBuilder("Looking up existing token for "); builder.append("client_id=" + authorizationRequest.getClientId()); builder.append(", scope=" + authorizationRequest.getScope()); builder.append(" and username="******"Existing access token=" + accessToken); if (accessToken != null && !accessToken.isExpired()) { logger.debug("User already approved with token=" + accessToken); // A token was already granted and is still valid, so this is already approved approved = true; } else { logger.debug("Checking explicit approval"); approved = userAuthentication.isAuthenticated() && approved; } return approved; }
public View getUnsuccessfulView( AuthorizationRequest authorizationRequest, OAuth2Exception failure) { if (authorizationRequest == null || authorizationRequest.getRedirectUri() == null) { // we have no redirect for the user. very sad. throw new UnapprovedClientAuthenticationException( "Authorization failure, and no redirect URI.", failure); } Map<String, String> query = new LinkedHashMap<String, String>(); query.put("error", failure.getOAuth2ErrorCode()); query.put("error_description", failure.getMessage()); if (authorizationRequest.getState() != null) { query.put("state", authorizationRequest.getState()); } if (failure.getAdditionalInformation() != null) { for (Map.Entry<String, String> additionalInfo : failure.getAdditionalInformation().entrySet()) { query.put(additionalInfo.getKey(), additionalInfo.getValue()); } } String url = append( authorizationRequest.getRedirectUri(), query, appendToFragment(authorizationRequest)); return new RedirectView(url, false, true, false); }
@Before public void setUp() { mockUserDatabase(userId, user); authorizationRequest = new AuthorizationRequest("client", Collections.singleton("read")); authorizationRequest.setResourceIds(new HashSet<>(Arrays.asList("client", "scim"))); Map<String, String> requestParameters = new HashMap<>(); authorizationRequest.setRequestParameters(requestParameters); authentication = new OAuth2Authentication( authorizationRequest.createOAuth2Request(), UaaAuthenticationTestFactory.getAuthentication(userId, userName, "*****@*****.**")); signerProvider = new SignerProvider(); signerProvider.setSigningKey(signerKey); signerProvider.setVerifierKey(verifierKey); tokenServices.setSignerProvider(signerProvider); endpoint.setTokenServices(tokenServices); Date oneSecondAgo = new Date(System.currentTimeMillis() - 1000); Date thirtySecondsAhead = new Date(System.currentTimeMillis() + 30000); approvalStore.addApproval( new Approval( userId, "client", "read", thirtySecondsAhead, ApprovalStatus.APPROVED, oneSecondAgo)); approvalStore.addApproval( new Approval( userId, "client", "write", thirtySecondsAhead, ApprovalStatus.APPROVED, oneSecondAgo)); tokenServices.setApprovalStore(approvalStore); clientDetailsService.setClientDetailsStore(clientDetailsStore); tokenServices.setClientDetailsService(clientDetailsService); accessToken = tokenServices.createAccessToken(authentication); }
@Test public void testClientWildcard() throws Exception { BaseClientDetails theclient = new BaseClientDetails( "client", "zones", "zones.*.admin", "authorization_code, password", "scim.read, scim.write", "http://*****:*****@vmware.com")); accessToken = tokenServices.createAccessToken(authentication); endpoint.checkToken(accessToken.getValue()); }
// 待改进,读取用户所拥有的权限以及客户端请求的权限,根据二者返回 @Override public Map<String, Object> getUserApprovalRequest( AuthorizationRequest authorizationRequest, Authentication userAuthentication) { Map<String, Object> model = new HashMap<String, Object>(); model.putAll(authorizationRequest.getRequestParameters()); return model; }
@Override public AuthorizationRequest updateAfterApproval( AuthorizationRequest authorizationRequest, Authentication userAuthentication) { Map<String, String> approvalParameters = authorizationRequest.getApprovalParameters(); Set<String> scopes = new LinkedHashSet(); for (Map.Entry<String, String> entry : approvalParameters.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); if (value.equals("true")) { scopes.add(key); } } authorizationRequest.setScope(scopes); String flag = approvalParameters.get(approvalParameter); boolean approved = flag != null && flag.toLowerCase().equals("true"); authorizationRequest.setApproved(approved); return authorizationRequest; }
/** * Basic access confirmation controller for OAuth2 * * @param model Model objects to be passed to the view * @param principal The principal user making the auth request * @return A ModelAndView for the access_confirmation page */ @RequestMapping("/api/oauth/confirm_access") public ModelAndView getAccessConfirmation(Map<String, Object> model, Principal principal) { // get the authorization request from the model AuthorizationRequest clientAuth = (AuthorizationRequest) model.remove("authorizationRequest"); logger.trace( "Token request recieved from " + clientAuth.getClientId() + " for " + principal.getName()); // get a list of the scopes from the request Set<String> scopes = clientAuth.getScope(); String join = Joiner.on(" & ").join(scopes); // add necessary information to the model model.put("auth_request", clientAuth); model.put("scopes", join); model.put("principal", principal); return new ModelAndView("oauth/access_confirmation", model); }
@Override public View getSuccessfulAuthorizationCodeView( AuthorizationRequest authorizationRequest, String authorizationCode) { if (authorizationCode == null) { throw new IllegalStateException("No authorization code found in the current request scope."); } Map<String, String> query = new LinkedHashMap<String, String>(); query.put("code", authorizationCode); String state = authorizationRequest.getState(); if (state != null) { query.put("state", state); } return new RedirectView( append(authorizationRequest.getRedirectUri(), query, false), false, true, false); }
public OAuth2AccessToken refreshAccessToken( String refreshTokenValue, AuthorizationRequest request) throws AuthenticationException { if (!supportRefreshToken) { throw new InvalidGrantException("Invalid refresh token: " + refreshTokenValue); } OAuth2RefreshToken refreshToken = tokenStore.readRefreshToken(refreshTokenValue); if (refreshToken == null) { throw new InvalidGrantException("Invalid refresh token: " + refreshTokenValue); } OAuth2Authentication authentication = tokenStore.readAuthenticationForRefreshToken(refreshToken); String clientId = authentication.getOAuth2Request().getClientId(); if (clientId == null || !clientId.equals(request.getClientId())) { throw new InvalidGrantException("Wrong client for this refresh token: " + refreshTokenValue); } // clear out any access tokens already associated with the refresh // token. tokenStore.removeAccessTokenUsingRefreshToken(refreshToken); if (isExpired(refreshToken)) { tokenStore.removeRefreshToken(refreshToken); throw new InvalidTokenException("Invalid refresh token (expired): " + refreshToken); } authentication = createRefreshedAuthentication(authentication, request.getScope()); if (!reuseRefreshToken) { tokenStore.removeRefreshToken(refreshToken); refreshToken = createRefreshToken(authentication); } OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken); tokenStore.storeAccessToken(accessToken, authentication); if (!reuseRefreshToken) { tokenStore.storeRefreshToken(refreshToken, authentication); } return accessToken; }
@Override public String retrieveSourceOrcid() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null) { return null; } // API if (OAuth2Authentication.class.isAssignableFrom(authentication.getClass())) { AuthorizationRequest authorizationRequest = ((OAuth2Authentication) authentication).getAuthorizationRequest(); return authorizationRequest.getClientId(); } // Delegation mode String realUserIfInDelegationMode = getRealUserIfInDelegationMode(authentication); if (realUserIfInDelegationMode != null) { return realUserIfInDelegationMode; } // Normal web user return retrieveEffectiveOrcid(authentication); }
@RequestMapping("/oauth/confirm_access") public ModelAndView getAccessConfirmation(@ModelAttribute AuthorizationRequest clientAuth) throws Exception { ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); TreeMap<String, Object> model = new TreeMap<String, Object>(); model.put("auth_request", clientAuth); model.put("client", client); return new ModelAndView("access_confirmation", model); }
private String appendAccessToken( AuthorizationRequest authorizationRequest, OAuth2AccessToken accessToken) { Map<String, Object> vars = new LinkedHashMap<String, Object>(); Map<String, String> keys = new HashMap<String, String>(); if (accessToken == null) { throw new InvalidRequestException("An implicit grant could not be made"); } vars.put("access_token", accessToken.getValue()); vars.put("token_type", accessToken.getTokenType()); String state = authorizationRequest.getState(); if (state != null) { vars.put("state", state); } Date expiration = accessToken.getExpiration(); if (expiration != null) { long expires_in = (expiration.getTime() - System.currentTimeMillis()) / 1000; vars.put("expires_in", expires_in); } String originalScope = authorizationRequest.getRequestParameters().get(OAuth2Utils.SCOPE); if (originalScope == null || !OAuth2Utils.parseParameterList(originalScope).equals(accessToken.getScope())) { vars.put("scope", OAuth2Utils.formatParameterList(accessToken.getScope())); } Map<String, Object> additionalInformation = accessToken.getAdditionalInformation(); for (String key : additionalInformation.keySet()) { Object value = additionalInformation.get(key); if (value != null) { keys.put("extra_" + key, key); vars.put("extra_" + key, value); } } // Do not include the refresh token (even if there is one) return append(authorizationRequest.getRedirectUri(), vars, keys, true); }
@RequestMapping("/oauth/confirm_access") public String confirm( @ModelAttribute AuthorizationRequest clientAuth, Map<String, Object> model, final HttpServletRequest request) throws Exception { if (clientAuth == null) { model.put( "error", "No authorizatioun request is present, so we cannot confirm access (we don't know what you are asking for)."); // response.sendError(HttpServletResponse.SC_BAD_REQUEST); } else { ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId()); model.put("auth_request", clientAuth); model.put("client", client); model.put( "message", "To confirm or deny access POST to the following locations with the parameters requested."); Map<String, Object> options = new HashMap<String, Object>() { { put( "confirm", new HashMap<String, String>() { { put("location", getLocation(request, "oauth/authorize")); put("path", getPath(request, "oauth/authorize")); put("key", "user_oauth_approval"); put("value", "true"); } }); put( "deny", new HashMap<String, String>() { { put("location", getLocation(request, "oauth/authorize")); put("path", getPath(request, "oauth/authorize")); put("key", "user_oauth_approval"); put("value", "false"); } }); } }; model.put("options", options); } return "access_confirmation"; }
@Test public void testOauthClient() throws Exception { AuthorizationRequest request = new AuthorizationRequest("foo", Collections.singleton("read")); request.setResourceIdsAndAuthoritiesFromClientDetails( new BaseClientDetails("foo", "", "", "client_credentials", "ROLE_CLIENT")); Authentication userAuthentication = null; OAuth2Request clientAuthentication = RequestTokenFactory.createOAuth2Request( request.getRequestParameters(), request.getClientId(), request.getAuthorities(), request.isApproved(), request.getScope(), request.getResourceIds(), request.getRedirectUri(), request.getResponseTypes(), request.getExtensions()); OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(clientAuthentication, userAuthentication); MethodInvocation invocation = new SimpleMethodInvocation(this, ReflectionUtils.findMethod(getClass(), "testOauthClient")); EvaluationContext context = handler.createEvaluationContext(oAuth2Authentication, invocation); Expression expression = handler.getExpressionParser().parseExpression("#oauth2.clientHasAnyRole('ROLE_CLIENT')"); assertTrue((Boolean) expression.getValue(context)); }
@Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; AuthorizationRequest authRequest = authRequestFactory.createAuthorizationRequest(createRequestMap(request.getParameterMap())); if (authRequest.getExtensions().get("prompt") != null) { // we have a "prompt" parameter String prompt = (String) authRequest.getExtensions().get("prompt"); if (prompt.equals("none")) { logger.info("Client requested no prompt"); // see if the user's logged in Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null) { // user's been logged in already (by session management) // we're OK, continue without prompting chain.doFilter(req, res); } else { // user hasn't been logged in, we need to "return an error" logger.info("User not logged in, no prompt requested, returning 403 from filter"); response.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied"); return; } } else if (prompt.equals("login")) { // first see if the user's already been prompted in this session HttpSession session = request.getSession(); if (session.getAttribute(PROMPTED) == null) { // user hasn't been PROMPTED yet, we need to check session.setAttribute(PROMPT_REQUESTED, Boolean.TRUE); // see if the user's logged in Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null) { // user's been logged in already (by session management) // log them out and continue SecurityContextHolder.getContext().setAuthentication(null); chain.doFilter(req, res); } else { // user hasn't been logged in yet, we can keep going since we'll get there chain.doFilter(req, res); } } else { // user has been PROMPTED, we're fine // but first, undo the prompt tag session.removeAttribute(PROMPTED); chain.doFilter(req, res); } } else { // prompt parameter is a value we don't care about, not our business chain.doFilter(req, res); } } else if (authRequest.getExtensions().get("max_age") != null) { String maxAge = (String) authRequest.getExtensions().get("max_age"); HttpSession session = request.getSession(); Date authTime = (Date) session.getAttribute(AuthenticationTimeStamper.AUTH_TIMESTAMP); Date now = new Date(); if (authTime != null) { Integer max = Integer.parseInt(maxAge); long seconds = (now.getTime() - authTime.getTime()) / 1000; if (seconds > max) { // session is too old, log the user out and continue SecurityContextHolder.getContext().setAuthentication(null); } } chain.doFilter(req, res); } else { // no prompt parameter, not our business chain.doFilter(req, res); } }
@Before public void setUp() { userAuthorities = new ArrayList<>(); userAuthorities.add(new SimpleGrantedAuthority("read")); userAuthorities.add(new SimpleGrantedAuthority("write")); userAuthorities.add(new SimpleGrantedAuthority("zones.myzone.admin")); userAuthorities.addAll(UaaAuthority.USER_AUTHORITIES); user = new UaaUser( userId, userName, "password", userEmail, userAuthorities, "GivenName", "FamilyName", new Date(System.currentTimeMillis() - 2000), new Date(System.currentTimeMillis() - 2000), OriginKeys.UAA, "externalId", false, IdentityZoneHolder.get().getId(), "salt", new Date(System.currentTimeMillis() - 2000)); mockUserDatabase(userId, user); authorizationRequest = new AuthorizationRequest("client", Collections.singleton("read")); authorizationRequest.setResourceIds(new HashSet<>(Arrays.asList("client", "scim"))); Map<String, String> requestParameters = new HashMap<>(); authorizationRequest.setRequestParameters(requestParameters); authentication = new OAuth2Authentication( authorizationRequest.createOAuth2Request(), UaaAuthenticationTestFactory.getAuthentication(userId, userName, "*****@*****.**")); signerProvider = new SignerProvider(); signerProvider.setSigningKey(signerKey); signerProvider.setVerifierKey(verifierKey); tokenServices.setSignerProvider(signerProvider); endpoint.setTokenServices(tokenServices); Date oneSecondAgo = new Date(System.currentTimeMillis() - 1000); Date thirtySecondsAhead = new Date(System.currentTimeMillis() + 30000); approvalStore.addApproval( new Approval() .setUserId(userId) .setClientId("client") .setScope("read") .setExpiresAt(thirtySecondsAhead) .setStatus(ApprovalStatus.APPROVED) .setLastUpdatedAt(oneSecondAgo)); approvalStore.addApproval( new Approval() .setUserId(userId) .setClientId("client") .setScope("write") .setExpiresAt(thirtySecondsAhead) .setStatus(ApprovalStatus.APPROVED) .setLastUpdatedAt(oneSecondAgo)); tokenServices.setApprovalStore(approvalStore); tokenServices.setTokenPolicy(new TokenPolicy(43200, 2592000)); defaultClient = new BaseClientDetails( "client", "scim, cc", "read, write", "authorization_code, password", "scim.read, scim.write", "http://localhost:8080/uaa"); clientDetailsStore = Collections.singletonMap("client", defaultClient); clientDetailsService.setClientDetailsStore(clientDetailsStore); tokenServices.setClientDetailsService(clientDetailsService); accessToken = tokenServices.createAccessToken(authentication); }
@Override public boolean isApproved( AuthorizationRequest authorizationRequest, Authentication userAuthentication) { return authorizationRequest.isApproved(); }
protected boolean appendToFragment(AuthorizationRequest authorizationRequest) { return authorizationRequest.getResponseTypes().contains("token"); }