本文源码:GitHub·点这里 || GitEE·点这里

一、模式形容

受权服务

验证第三方服务的身份,验证邮箱用户的身份,记录和治理认证Token,为资源服务器提供Token校验。场景:第三方网站借助用户的邮箱登录,并拜访邮箱账户的根底信息,头像、名称等。

资源服务

第三方服务通过邮箱账户登录后须要获取的一些信息,即了解为资源,存储邮箱账户的数据资源。

第三方服务

即借助邮箱用户的账户,疾速登录第三个服务,免去繁冗的注册流程,有助于疾速积攒新用户。

交互流程

第三方服务给用户凋谢疾速邮箱登录性能,疏导用户调到邮箱认证服务,通过认证后返回身份令牌到第三方服务,第三方服务携带令牌拜访邮箱的资源服务,获取一些根本的邮箱用户信息。

二、我的项目配置管理

1、案例构造

外围依赖

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId></dependency><dependency>    <groupId>org.springframework.security.oauth</groupId>    <artifactId>spring-security-oauth2</artifactId>    <version>2.1.3.RELEASE</version></dependency><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-security</artifactId></dependency>

这里有两个外围组件依赖:OAuth2组件和Security组件。

模块划分

  • auth-server:受权服务
  • resource-server:资源服务器
  • third-server:第三个服务

2、配置形容

【受权服务】

OAuth2配置

这里的配置管理的是第三方的受权流程和发放给第三方的身份证明ClientID和明码,理论的场景就是第三方借助邮箱账号登录,首先就是向邮箱管理方提供资料,获取拜访邮箱服务的身份证明,而后能力对接凋谢服务,这种模式在第三方对接业务中很常见。

/** * 模仿第三方受权配置 */@EnableAuthorizationServer@Configurationpublic class AuthConfig extends AuthorizationServerConfigurerAdapter {    @Resource    ClientDetailsService clientDetailsService;    /**     * 资源服务器校验Token     */    @Override    public void configure(AuthorizationServerSecurityConfigurer security) {        security.checkTokenAccess("permitAll()").allowFormAuthenticationForClients();    }    /**     * 第三方客户端申请配置,和资源服务拜访的配置,不设置默认都能够拜访,提供默认回调地址     */    @Override    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {        clients.inMemory()                .withClient("third01")                .secret(new BCryptPasswordEncoder().encode("third01"))                .resourceIds("resource-01")                .authorizedGrantTypes("authorization_code","refresh_token")                .scopes("all")                .redirectUris("http://localhost:8082/notify.html");    }    /**     * 配置拜访端点     */    @Override    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {        endpoints.authorizationCodeServices(authorizationCodeServices()).tokenServices(tokenServices());    }    /**     * 内存治理     */    @Bean    AuthorizationCodeServices authorizationCodeServices() {        return new InMemoryAuthorizationCodeServices();    }    /**     * Token治理规定     */    @Bean    AuthorizationServerTokenServices tokenServices() {        DefaultTokenServices services = new DefaultTokenServices();        services.setClientDetailsService(clientDetailsService);        services.setSupportRefreshToken(true);        services.setTokenStore(tokenStore());        services.setAccessTokenValiditySeconds(3600);        services.setRefreshTokenValiditySeconds(3600*7);        return services;    }    @Bean    TokenStore tokenStore() {        return new InMemoryTokenStore();    }}

通常须要数据库存储第三方信息,能够到第OAuth2开源我的项目中,获取表构造放到本地数据库中,而后这里换成数据源加载模式即可,简略的流程治理都在源码里写了SQL语句,数据源引入即可。

Security配置

/** * 模仿本地用户配置 */@Configurationpublic class SecurityConfig extends WebSecurityConfigurerAdapter {    /**     * 明码加密形式     */    @Bean    public PasswordEncoder passwordEncoder(){        return new BCryptPasswordEncoder();    }    /**     * 内存中虚构用户和角色     */    @Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception {        auth.inMemoryAuthentication()                .withUser("user")                .password(new BCryptPasswordEncoder().encode("123456"))                .roles("user");    }    /**     * 表单登录     */    @Override    protected void configure(HttpSecurity http) throws Exception {        http.csrf().disable().formLogin();    }}

基于这里的配置管理邮箱用户的认证流程,例如应用邮箱账号密码登录验证,判断受权是否成立,这里治理的是服务本地的邮箱账号,基于数据源存储数据在上面案例中都有。

  • 案例一:JWT组件治理身份验证机制
  • 案例二:Shiro组件实现用户权限治理
  • 案例三:Security用户平安认证流程

对于Spring框架中平安认证的相干的几个组件,在应用OAuth2之前能够先理解一下。

【资源服务】

次要性能有三块,配置第三方携带的Token身份令牌校验机制,即拜访受权服务校验接口,这里是OAuth2自定义好的接口;配置resourceId资源服务的编号,用来管制第三个服务能拜访的资源服务范畴,属于大的权限点管制;模仿校验用户的Role角色,较精密的管制权限。

/** * 资源服务治理配置 */@Configuration@EnableResourceServerpublic class ResourceServerConfig extends ResourceServerConfigurerAdapter {    /**     * Token令牌校验     */    @Bean    RemoteTokenServices tokenServices() {        RemoteTokenServices services = new RemoteTokenServices();        services.setCheckTokenEndpointUrl("http://localhost:8080/oauth/check_token");        services.setClientId("third01");        services.setClientSecret("third01");        return services;    }    /**     * 服务资源ID配置     */    @Override    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {        resources.resourceId("resource-01").tokenServices(tokenServices());    }    /**     * 模仿用户权限规定     */    @Override    public void configure(HttpSecurity http) throws Exception {        http.authorizeRequests()                .antMatchers("/user/**").hasRole("user")                .anyRequest().authenticated();    }}

【第三方服务】

次要提供两个流程的模仿:申请受权服务获取身份令牌;携带身份令牌申请资源服务获取数据。这里则是受权码回调接口的解决形式。

@Controllerpublic class NotifyController {    private static final Logger LOG = LoggerFactory.getLogger(NotifyController.class);    @Resource    private RestTemplate restTemplate;    @GetMapping("/notify.html")    public String notify(String code, Model model) {        if (code != null) {            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();            map.add("code", code);            map.add("client_id", "third01");            map.add("client_secret", "third01");            map.add("redirect_uri", "http://localhost:8082/notify.html");            map.add("grant_type", "authorization_code");            Map<String,String> resp = restTemplate.postForObject("http://localhost:8080/oauth/token", map, Map.class);            String accessToken = resp.get("access_token");            LOG.info("身份令牌:{}",accessToken);            HttpHeaders headers = new HttpHeaders();            headers.add("Authorization", "Bearer " + accessToken);            HttpEntity<Object> httpEntity = new HttpEntity<>(headers);            ResponseEntity<String> entity = restTemplate.exchange("http://localhost:8081/user/resource", HttpMethod.GET, httpEntity, String.class);            model.addAttribute("notifyMsg", entity.getBody());        }        return "notify";    }}

三、测试流程

通过上述测试流程,比照常见的第三方登录机制,了解OAuth2的受权码模式。

四、源代码地址

GitHub·地址https://github.com/cicadasmile/middle-ware-parentGitEE·地址https://gitee.com/cicadasmile/middle-ware-parent

举荐浏览:编程体系整顿

序号项目名称GitHub地址GitEE地址举荐指数
01Java形容设计模式,算法,数据结构GitHub·点这里GitEE·点这里☆☆☆☆☆
02Java根底、并发、面向对象、Web开发GitHub·点这里GitEE·点这里☆☆☆☆
03SpringCloud微服务根底组件案例详解GitHub·点这里GitEE·点这里☆☆☆
04SpringCloud微服务架构实战综合案例GitHub·点这里GitEE·点这里☆☆☆☆☆
05SpringBoot框架根底利用入门到进阶GitHub·点这里GitEE·点这里☆☆☆☆
06SpringBoot框架整合开发罕用中间件GitHub·点这里GitEE·点这里☆☆☆☆☆
07数据管理、分布式、架构设计根底案例GitHub·点这里GitEE·点这里☆☆☆☆☆
08大数据系列、存储、组件、计算等框架GitHub·点这里GitEE·点这里☆☆☆☆☆