spring security和oauth2.0

314 阅读3分钟

引入maven依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-security</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-oauth2</artifactId>
    </dependency>
    


    <!-- 将token存储在redis中 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
    
    

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.3</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>


    
<dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR12</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.3.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

    </dependencies>
    
    

新增 spring security配置类 SecurityConfig

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        /*
        * authorizeRequests()方法表示开启权限配置
        * formLogin()表示开启表单登录配置,
        * loginPage用来配置登录页面地址;
        * loginProcessingUrl用来配置登录接口地址;
        * defaultSuccessUrl表示登录成功后的跳转地址;
        * csrf().disable()表示禁用CSRF防御功能
        failureUrl表示登录失败后重定向到mylogin.html页面。
        * */
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/doLogin")
                   // 配置自定义登录成功处理器
                  .successHandler(new MyAuthenticationSuccessHandler())
                  .defaultSuccessUrl("/index")
                  .failureUrl("/login.html")
                   // 配置自定义登录失败处理器
                  .failureHandler(new MyAuthenticationFailureHandler())
                  // 设置登录用户名参数
                  .usernameParameter("uname")
                    // 设置登录密码参数
                   .passwordParameter("passwd")
                   .permitAll()
                // 配置注销
                .and()
                .logout()
                .logoutUrl("/logout")
                // invalidateHttpSession表示是否使session失效,默认为true。
                .invalidateHttpSession(true)
                //clearAuthentication表示是否清除认证信息,默认为true。
                .clearAuthentication(true)
                // logoutSuccessUrl表示注销登录后的跳转地址。
                .logoutSuccessUrl("/mylogin.html")
                .logoutSuccessHandler(((httpServletRequest, httpServletResponse, authentication) -> {
                    httpServletResponse.setContentType("application/json;charset=utf-8");
                    Map<String, Object> resp = new HashMap<>();
                    resp.put("status", 500);
                    resp.put("msg", "注销成功");
                    ObjectMapper om = new ObjectMapper();
                    String s = om.writeValueAsString(resp);
                    httpServletResponse.getWriter().write(s);
                }))
                .permitAll()
                .and()
                .csrf().disable();


                //        将自定义的Filter放在指定Filter后
                //      http.addFilterAfter();
                //        将自定义的Filter放在指定Filter后
                //      http.addFilterBefore();
                //        将自定义的Filter替换指定的原生Filter
                //       http.addFilterAt();

                 http.addFilterAt(loginFilter(), UsernamePasswordAuthenticationFilter.class);
    }


}

设置数据库用户认证

新增 MyUserDetailsService,验证用户信息

@Service
public class MyUserDetailsService implements UserDetailsService  {

    @Autowired
    UserMapper userMapper;


    @Override
    public UserDetails loadUserByUsername(String orgCode)
            throws UsernameNotFoundException {
        User user = userMapper.loadUserByUsername(orgCode);
        if (user == null) {
            throw new UsernameNotFoundException("柜员不存在");
        }
        user.setRoles(userMapper.getRolesByUid(user.getId()));
        OauthAspect.setUserDetails(user);
        return user;
    }


}

在SecurityConfig配置类中,加入以下配置


@Autowired
MyUserDetailsService myUserDetailsService;


@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(myUserDetailsService);
}

忽略文件 在SecurityConfig配置类中,加入以下配置

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring()
            .antMatchers("/login.html", "/css/**", "/js/**","/images/**");
}

设置加密在SecurityConfig配置类中,加入以下配置

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

配置spring security oauht2认证服务器

新增 AuthorizationServerConfig

客户端基于内存配置

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    // 使用内存存储
    clients.inMemory()
            //配置client_id
            .withClient("admin")
            //配置client-secret
            .secret(passwordEncoder.encode("112233"))
            //配置redirect_uri,用于授权成功后跳转
            .redirectUris("http://www.baidu.com")
            //配置申请的权限范围
            .scopes("all")
            //配置grant_type,表示授权类型
            .authorizedGrantTypes("authorization_code","password", "refresh_token");
    }
}

客户端基于数据库配置,AuthorizationServerConfig添加以下配置

@Bean
ClientDetailsService clientDetailsService() {
    return new JdbcClientDetailsService(dataSource);
}

将token信息存redis

新增 RedisTokenStoreConfig

@Configuration
public class RedisTokenStoreConfig {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    public TokenStore redisTokenStore(){
        return new RedisTokenStore(redisConnectionFactory);
    }

}

AuthorizationServerConfig添加以下配置

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    // 密码模式设置
    endpoints.authenticationManager(authenticationManager)
    // 用户校验
            .userDetailsService(myUserDetailsService)
            .tokenStore(tokenStore);
}

设置check_token端点

@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    //所有人可访问 /oauth/token_key 后面要获取公钥, 默认拒绝访问
    security.tokenKeyAccess("permitAll()");
    // 认证后可访问 /oauth/check_token , 默认拒绝访问
    security.checkTokenAccess("isAuthenticated()");
}

配置spring security oauth2 资源服务器

新增OAuth2ResourceServer

@Configuration
@EnableResourceServer // 标识为资源服务器, 所有发往当前服务的请求,都会去请求头里找token,找不到或 验证不通过不允许访问
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .requestMatchers()
                .antMatchers("/order/**");
    }

}

在配置文件加入配置

security:
  oauth2:
    client:
      client-id: admin
      client-secret: 112233
      access-token-uri: http://localhost:7775/oauth/token
      grant-type: password
      scope: all
    resource:
      token-info-uri: http://localhost:7775/oauth/check_token