@Override public AuthorizationRequest createAuthorizationRequest(Map<String, String> parameters) { String clientId = parameters.get("client_id"); if (clientId == null) { throw new InvalidClientException("A client id must be provided"); } ClientDetails client = clientDetailsService.loadClientByClientId(clientId); String requestNonce = parameters.get("nonce"); // Only process if the user is authenticated. If the user is not authenticated yet, this // code will be called a second time once the user is redirected from the login page back // to the auth endpoint. Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (requestNonce != null && principal != null && principal instanceof User) { // Check request nonce for reuse Collection<Nonce> clientNonces = nonceService.getByClientId(client.getClientId()); for (Nonce nonce : clientNonces) { String nonceVal = nonce.getValue(); if (nonceVal.equals(requestNonce)) { throw new NonceReuseException(client.getClientId(), nonce); } } // Store nonce Nonce nonce = new Nonce(); nonce.setClientId(client.getClientId()); nonce.setValue(requestNonce); DateTime now = new DateTime(new Date()); nonce.setUseDate(now.toDate()); DateTime expDate = now.plus(nonceStorageDuration); Date expirationJdkDate = expDate.toDate(); nonce.setExpireDate(expirationJdkDate); nonceService.save(nonce); } Set<String> scopes = OAuth2Utils.parseParameterList(parameters.get("scope")); if ((scopes == null || scopes.isEmpty())) { // TODO: do we want to allow default scoping at all? // If no scopes are specified in the incoming data, it is possible to default to the client's // registered scopes, but minus the "openid" scope. OpenID Connect requests MUST have the // "openid" scope. Set<String> clientScopes = client.getScope(); if (clientScopes.contains("openid")) { clientScopes.remove("openid"); } scopes = clientScopes; } DefaultAuthorizationRequest request = new DefaultAuthorizationRequest( parameters, Collections.<String, String>emptyMap(), clientId, scopes); request.addClientDetails(client); return request; }
/** * Create an authorization request applying various UAA rules to the authorizationParameters and * the registered client details. * * <ul> * <li>For client_credentials grants, the default scopes are the client's granted authorities * <li>For other grant types the default scopes are the registered scopes in the client details * <li>Only scopes in those lists are valid, otherwise there is an exception * <li>If the scopes contain separators then resource ids are extracted as the scope value up to * the last index of the separator * <li>Some scopes can be hard-wired to resource ids (like the open id connect values), in which * case the separator is ignored * </ul> * * @see * org.springframework.security.oauth2.provider.AuthorizationRequestFactory#createAuthorizationRequest(java.util.Map, * java.lang.String, java.lang.String, java.util.Set) */ @Override public AuthorizationRequest createAuthorizationRequest( Map<String, String> authorizationParameters) { String clientId = authorizationParameters.get("client_id"); BaseClientDetails clientDetails = new BaseClientDetails(clientDetailsService.loadClientByClientId(clientId)); Set<String> scopes = OAuth2Utils.parseParameterList(authorizationParameters.get("scope")); String grantType = authorizationParameters.get("grant_type"); if ((scopes == null || scopes.isEmpty())) { if ("client_credentials".equals(grantType)) { // The client authorities should be a list of scopes scopes = AuthorityUtils.authorityListToSet(clientDetails.getAuthorities()); } else { // The default for a user token is the scopes registered with // the client scopes = clientDetails.getScope(); } } Set<String> scopesFromExternalAuthorities = null; if (!"client_credentials".equals(grantType) && securityContextAccessor.isUser()) { scopes = checkUserScopes(scopes, securityContextAccessor.getAuthorities(), clientDetails); // TODO: will the grantType ever contain client_credentials or // authorization_code // External Authorities are things like LDAP groups that will be // mapped to Oauth scopes // Add those scopes to the request. These scopes will not be // validated against the scopes // registered to a client. // These scopes also do not need approval. The fact that they are // already in an external // group communicates user approval. Denying approval does not mean // much scopesFromExternalAuthorities = findScopesFromAuthorities(authorizationParameters.get("authorities")); } Set<String> resourceIds = getResourceIds(clientDetails, scopes); clientDetails.setResourceIds(resourceIds); DefaultAuthorizationRequest request = new DefaultAuthorizationRequest(authorizationParameters); if (!scopes.isEmpty()) { request.setScope(scopes); } if (scopesFromExternalAuthorities != null) { Map<String, String> existingAuthorizationParameters = new LinkedHashMap<String, String>(); existingAuthorizationParameters.putAll(request.getAuthorizationParameters()); existingAuthorizationParameters.put( "external_scopes", OAuth2Utils.formatParameterList(scopesFromExternalAuthorities)); request.setAuthorizationParameters(existingAuthorizationParameters); } request.addClientDetails(clientDetails); return request; }
@Test public void adminClientIsAdmin() throws Exception { BaseClientDetails client = new BaseClientDetails(); client.setAuthorities(UaaAuthority.ADMIN_AUTHORITIES); DefaultAuthorizationRequest authorizationRequest = new DefaultAuthorizationRequest("admin", null); authorizationRequest.addClientDetails(client); SecurityContextHolder.getContext() .setAuthentication(new OAuth2Authentication(authorizationRequest, null)); assertTrue(new DefaultSecurityContextAccessor().isAdmin()); }
@Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { final boolean debug = logger.isDebugEnabled(); final HttpServletRequest request = (HttpServletRequest) req; final HttpServletResponse response = (HttpServletResponse) res; try { Authentication credentials = extractCredentials(request); if (credentials != null) { if (debug) { logger.debug("Authentication credentials found for '" + credentials.getName() + "'"); } Authentication authResult = authenticationManager.authenticate(credentials); if (debug) { logger.debug("Authentication success: " + authResult.getName()); } Authentication requestingPrincipal = SecurityContextHolder.getContext().getAuthentication(); if (requestingPrincipal == null) { throw new BadCredentialsException( "No client authentication found. Remember to put a filter upstream of the LoginAuthenticationFilter."); } String clientId = request.getParameter("client_id"); if (null == clientId) { logger.error("No client_id in the request"); throw new BadCredentialsException("No client_id in the request"); } // Check that the client exists ClientDetails authenticatingClient = clientDetailsService.loadClientByClientId(clientId); if (authenticatingClient == null) { throw new BadCredentialsException("No client " + clientId + " found"); } DefaultAuthorizationRequest authorizationRequest = new DefaultAuthorizationRequest( getSingleValueMap(request), null, authenticatingClient.getClientId(), getScope(request)); if (requestingPrincipal.isAuthenticated()) { // Ensure the OAuth2Authentication is authenticated authorizationRequest.setApproved(true); } SecurityContextHolder.getContext() .setAuthentication(new OAuth2Authentication(authorizationRequest, authResult)); onSuccessfulAuthentication(request, response, authResult); } } catch (AuthenticationException failed) { SecurityContextHolder.clearContext(); if (debug) { logger.debug("Authentication request for failed: " + failed); } onUnsuccessfulAuthentication(request, response, failed); authenticationEntryPoint.commence(request, response, failed); return; } chain.doFilter(request, response); }