赞
踩
调用/oauth/authorize接口时,代码首先进入org.springframework.web.method.support.InvocableHandlerMethod类的invokeForRequest方法;代码如下:
- @Nullable
- public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
- Object... providedArgs) throws Exception {
-
- Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
- if (logger.isTraceEnabled()) {
- logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
- "' with arguments " + Arrays.toString(args));
- }
- Object returnValue = doInvoke(args);
- if (logger.isTraceEnabled()) {
- logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
- "] returned [" + returnValue + "]");
- }
- return returnValue;
- }
通过Object returnValue = doInvoke(args);方法调用org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint类的authorize方法;
- @RequestMapping(value = "/oauth/authorize")
- public ModelAndView authorize(Map<String, Object> model, @RequestParam Map<String, String> parameters,
- SessionStatus sessionStatus, Principal principal) {
-
- // Pull out the authorization request first, using the OAuth2RequestFactory. All further logic should
- // query off of the authorization request instead of referring back to the parameters map. The contents of the
- // parameters map will be stored without change in the AuthorizationRequest object once it is created.
- 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 = getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId());
-
- // The resolved redirect URI is either the redirect_uri from the parameters or the one from
- // clientDetails. Either way we need to store it on the AuthorizationRequest.
- 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);
-
- // We intentionally only validate the parameters requested by the client (ignoring any data that may have
- // been added to the request by the manager).
- oauth2RequestValidator.validateScope(authorizationRequest, client);
-
- // Some systems may allow for approval decisions to be remembered or approved by default. Check for
- // such logic here, and set the approved flag on the authorization request accordingly.
- authorizationRequest = userApprovalHandler.checkForPreApproval(authorizationRequest,
- (Authentication) principal);
- // TODO: is this call necessary?
- boolean approved = userApprovalHandler.isApproved(authorizationRequest, (Authentication) principal);
- authorizationRequest.setApproved(approved);
-
- // Validation is all done, so we can check for auto approval...
- if (authorizationRequest.isApproved()) {
- if (responseTypes.contains("token")) {
- return getImplicitGrantResponse(authorizationRequest);
- }
- if (responseTypes.contains("code")) {
- return new ModelAndView(getAuthorizationCodeResponse(authorizationRequest,
- (Authentication) principal));
- }
- }
-
- // 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);
-
- return getUserApprovalPageResponse(model, authorizationRequest, (Authentication) principal);
-
- }
- catch (RuntimeException e) {
- sessionStatus.setComplete();
- throw e;
- }
-
- }
在这个方法中,如果principal为null时即生成User must be authenticated with Spring Security before authorization can be completed.异常。
- if (!(principal instanceof Authentication) || !((Authentication) principal).isAuthenticated()) {
- throw new InsufficientAuthenticationException(
- "User must be authenticated with Spring Security before authorization can be completed.");
- }
principal在org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver类的resolveArgument方法中生成的。在resolveArgument方法中第162行中 Principal userPrincipal = request.getUserPrincipal();如果request中不存在用户信息,则Principal 无法取得,造成参数为Null情况。
- @Nullable
- private Object resolveArgument(Class<?> paramType, HttpServletRequest request) throws IOException {
- if (HttpSession.class.isAssignableFrom(paramType)) {
- HttpSession session = request.getSession();
- if (session != null && !paramType.isInstance(session)) {
- throw new IllegalStateException(
- "Current session is not of type [" + paramType.getName() + "]: " + session);
- }
- return session;
- }
- else if (pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) {
- return PushBuilderDelegate.resolvePushBuilder(request, paramType);
- }
- else if (InputStream.class.isAssignableFrom(paramType)) {
- InputStream inputStream = request.getInputStream();
- if (inputStream != null && !paramType.isInstance(inputStream)) {
- throw new IllegalStateException(
- "Request input stream is not of type [" + paramType.getName() + "]: " + inputStream);
- }
- return inputStream;
- }
- else if (Reader.class.isAssignableFrom(paramType)) {
- Reader reader = request.getReader();
- if (reader != null && !paramType.isInstance(reader)) {
- throw new IllegalStateException(
- "Request body reader is not of type [" + paramType.getName() + "]: " + reader);
- }
- return reader;
- }
- else if (Principal.class.isAssignableFrom(paramType)) {
- Principal userPrincipal = request.getUserPrincipal();
- if (userPrincipal != null && !paramType.isInstance(userPrincipal)) {
- throw new IllegalStateException(
- "Current user principal is not of type [" + paramType.getName() + "]: " + userPrincipal);
- }
- return userPrincipal;
- }
- else if (HttpMethod.class == paramType) {
- return HttpMethod.resolve(request.getMethod());
- }
- else if (Locale.class == paramType) {
- return RequestContextUtils.getLocale(request);
- }
- else if (TimeZone.class == paramType) {
- TimeZone timeZone = RequestContextUtils.getTimeZone(request);
- return (timeZone != null ? timeZone : TimeZone.getDefault());
- }
- else if (ZoneId.class == paramType) {
- TimeZone timeZone = RequestContextUtils.getTimeZone(request);
- return (timeZone != null ? timeZone.toZoneId() : ZoneId.systemDefault());
- }
-
- // Should never happen...
- throw new UnsupportedOperationException("Unknown parameter type: " + paramType.getName());
- }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。