Spring Security Oauth2系列(七)

摘要:

今天来给大家分享一下期待已久的oauth2回调地址的设置,相信接触过oauth2的很多coder已经按捺不住激动的心情了吧。因为这个回调地址的配置能够让授权码模式的运用的主动权掌握在自己的手中,可以根据自己的不同项目的实际情况设置不同的回调,例如社区的GitHub的示例:Spring Cloud Security系列教程一:入门

DefaultRedirectResolver

首先分析一下org.springframework.security.oauth2.provider.endpoint.DefaultRedirectResolver源码:

 public String resolveRedirect(String requestedRedirect, ClientDetails client) throws OAuth2Exception {
        Set<String> authorizedGrantTypes = client.getAuthorizedGrantTypes();
        if (authorizedGrantTypes.isEmpty()) {
            throw new InvalidGrantException("A client must have at least one authorized grant type.");
        } else if (!this.containsRedirectGrantType(authorizedGrantTypes)) {
            throw new InvalidGrantException("A redirect_uri can only be used by implicit or authorization_code grant types.");
        } else {
            Set<String> redirectUris = client.getRegisteredRedirectUri();
            if (redirectUris != null && !redirectUris.isEmpty()) {
                return this.obtainMatchingRedirect(redirectUris, requestedRedirect);
            } else if (StringUtils.hasText(requestedRedirect)) {
                return requestedRedirect;
            } else {
                throw new InvalidRequestException("A redirect_uri must be supplied.");
            }
        }
    }

对重定向路径进行解析,如果不进行设置默认就是当前路径,这里指的当前路径是指:比如当你在访问security进行了权限控制的路径http://localhost:8080/client时候,跳转到oauth2的登陆首页,此时当前页面指的就是http://localhost:8080/client

 private String obtainMatchingRedirect(Set<String> redirectUris, String requestedRedirect) {
        Assert.notEmpty(redirectUris, "Redirect URIs cannot be empty");
        if (redirectUris.size() == 1 && requestedRedirect == null) {
            return (String)redirectUris.iterator().next();
        } else {
            Iterator var3 = redirectUris.iterator();

            String redirectUri;
            do {
                if (!var3.hasNext()) {
                    throw new RedirectMismatchException("Invalid redirect: " + requestedRedirect + " does not match one of the registered values: " + redirectUris.toString());
                }

                redirectUri = (String)var3.next();
            } while(requestedRedirect == null || !this.redirectMatches(requestedRedirect, redirectUri));

            return requestedRedirect;
        }
    }

这个方法是来判断客户端的设置回调地址是否和服务端的回调地址一致

AbstractRedirectResourceDetails

核心方法解析,AbstractRedirectResourceDetails是一个抽象类,位于
org.springframework.security.oauth2.client.token.grant.redirect.AbstractRedirectResourceDetails
一起来看源代码吧

package org.springframework.security.oauth2.client.token.grant.redirect;

import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.AccessTokenRequest;

public abstract class AbstractRedirectResourceDetails extends BaseOAuth2ProtectedResourceDetails {
    private String preEstablishedRedirectUri;
    private String userAuthorizationUri;
    private boolean useCurrentUri = true;

    public AbstractRedirectResourceDetails() {
    }

    public void setUseCurrentUri(boolean useCurrentUri) {
        this.useCurrentUri = useCurrentUri;
    }

    public boolean isUseCurrentUri() {
        return this.useCurrentUri;
    }

    public String getUserAuthorizationUri() {
        return this.userAuthorizationUri;
    }

    public void setUserAuthorizationUri(String userAuthorizationUri) {
        this.userAuthorizationUri = userAuthorizationUri;
    }

    public String getPreEstablishedRedirectUri() {
        return this.preEstablishedRedirectUri;
    }

    public void setPreEstablishedRedirectUri(String preEstablishedRedirectUri) {
        //此处可以在客户端进行自定义设置
        this.preEstablishedRedirectUri = preEstablishedRedirectUri;
    }

    public String getRedirectUri(AccessTokenRequest request) {
        String redirectUri = (String)request.getFirst("redirect_uri");
        if (redirectUri == null && request.getCurrentUri() != null && this.useCurrentUri) {
            redirectUri = request.getCurrentUri();
        }

        if (redirectUri == null && this.getPreEstablishedRedirectUri() != null) {
            redirectUri = this.getPreEstablishedRedirectUri();
        }
      //返回回调地址
        return redirectUri;
    }
}

源码特别简单,这里不做过多的解释,部分关键配置我给大家贴出来
我的网关服务配置如下:

security:
  oauth2:
    client:
      client-id: fbed1d1b4b1449daa4bc49397cbe2350
      client-secret: fbed1d1b4b1449daa4bc49397cbe2350
      access-token-uri: http://localhost:8088/oauth/token
      user-authorization-uri: http://localhost:8088/oauth/authorize
      scope: read,write
      pre-established-redirect-uri: http://localhost:8080/session
      use-current-uri: false//此处特别重要一定要配置,否则不会生效,配置了自定义的回调地址就必须将默认的回调禁止,原因不做过多说明。
    resource:
      user-info-uri: http://localhost:8088/user
      prefer-token-info: false

我的oauth2关键配置如下:

     @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

        clients.inMemory()
                .withClient("fbed1d1b4b1449daa4bc49397cbe2350")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
                .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
                .scopes("read","write")
                .secret("fbed1d1b4b1449daa4bc49397cbe2350")
                .accessTokenValiditySeconds(120)//Access token is only valid for 2 minutes.
                .refreshTokenValiditySeconds(600)//Refresh token is only valid for 10 minutes.
                .redirectUris("http://localhost:8080/session");

    }

总结:

该篇文章主要讲了oauth2 的回调地址,相信是大家期待已久的功能点了,由于工作上的原因,完成这个分析的主要功能还是我的一个朋友张顺,有问题的大家继续在评论上提出来,希望能够在今后的项目实践中将oauth2的优势体现得淋漓尽致!
参考本人github地址:https://github.com/dqqzj/spring4all/tree/master/oauth2

猜你喜欢

转载自blog.csdn.net/sinat_24798023/article/details/80537179