spring boot Security Oauth2.0最简版本集成

spring boot Security Oauth2.0最简版本集成

搭建最简版本,工具IntelliJ idea,构建方式maven,话不多说,上代码
请同学们理性看待最简开发模式,真实开发涉及的内容非常多,只做思路

pom文件

<!-- security依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.3.3.RELEASE</version>
        </dependency>

        <!--web依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>

用户实体

为了方便操作,给用户赋权限(上篇使用了Security 的 USER对象,这次换个方式耍耍吧)

/**
 * @Title: LoginAppUser
 * @description: 用户信息管理
 * @author: LIUFANG
 * @create: 2020/3/13 12:54
 * @Version: v1.0
 */
@Getter
@Setter
public class LoginAppUser implements UserDetails {

    private Long id;
    private String username;
    private String password;
    private String nickname;
    private String headImgUrl;
    private String phone;
    private Integer sex;
    /**
     * 状态
     */
    private Boolean enabled;
    private String type;
    private String deptId;
    private String deptName;
    private Date createTime;
    private Date updateTime;

    private Set<String> sysRoles;

    private Set<String> permissions;
	/**权限的操作直接放在此处了,简单粗暴,如果你开心,你可以把类做的细化一点*/
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Collection<GrantedAuthority> collection = new HashSet<>();
        /**为什么加ROLE_,看了一下源码,你可以理解为:区分资源和权限的标识符*/
        collection.add(new SimpleGrantedAuthority("ROLE_"+"USER"));
        return collection;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
    @Override
    public String getUsername() {
        /**写死的数据,真实开发查询数据库就OK了*/
        return "user";
    }

UserDetailsService 不解释

/**
 * @Title: MyUserDetailsService
 * @description: 用户管理
 * @author: LIUFANG
 * @create: 2020/3/13 9:27
 * @Version: v1.0
 */
@Component
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private PasswordEncoder userPasswordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LoginAppUser loginAppUser = new LoginAppUser();
        loginAppUser.setUsername("user");
        loginAppUser.setPassword(userPasswordEncoder.encode("123456"));
        return loginAppUser;
    }
}

WebSecurityConfig

spring security的配置

/**
 * @Title: SecurityConfig
 * @description: 权限配置
 * @author: LIUFANG
 * @create: 2020/3/13 9:12
 * @Version: v1.0
 */
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyUserDetailsService userDetailsService;

    /**
     * 一定要将 userDetailsService 设置到 AuthenticationManagerBuilder 中
     * 不然后面校验ClientDetailsService时会找不到UsernamePasswordToken的Provider
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(userPasswordEncoder());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasAnyRole("ADMIN","USER")
                .antMatchers("/test").authenticated()
                .anyRequest().authenticated().and()
                .httpBasic().and()
                .csrf()
                .disable();
    }

    @Bean
    public PasswordEncoder userPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }


    /**
     * 覆盖WebSecurityConfigurerAdapter类(本类集成的爸爸)authenticationManagerBean的方法,最终要的一点,重写的时候,直接使用super就OK,这波操作给6分
     * 注意的是,这个bean不重写,在OauthAuthorizationServerConfig是无法获取的,这个是个小坑
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception{
        return super.authenticationManager();
    }

Oauth 配置类

/**
 * @Title: OauthAuthorizationServerConfig
 * @description: Oauth2.0配置
 * @author: LIUFANG
 * @create: 2020/3/13 10:22
 * @Version: v1.0
 */
@Configuration
@EnableAuthorizationServer
public class OauthAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    /**这个地方需要注意一下,这个bean必须自行创建出来,参照WebSecurityConfig类*/
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private MyUserDetailsService userDetailsService;

    /**
     * 配置访问端点和令牌服务
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        /**注意这个allowFormAuthenticationForClients,开启表单验证*/
        security
                .tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()")
                .allowFormAuthenticationForClients();
    }

    /**
     * 用来配置客户端详情服务
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        /**client信息,可以存储数据库,可以redis,也可以存储内存,看你心情*/
        clients.inMemory()
                .withClient("system")
                .secret(passwordEncoder.encode("123456"))
                .authorizedGrantTypes("authorization_code", "refresh_token", "password")
                .scopes("app");
    }

    /**
     * 配置token
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        /**直接存储内存*/
        endpoints
                .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
                .authenticationManager(authenticationManager)
                .tokenStore(new InMemoryTokenStore())
                .userDetailsService(userDetailsService);

    }
}

controller调用

/**
 * @Title: MyController
 * @description: 测试Controller
 * @author: LIUFANG
 * @create: 2020/3/13 10:56
 * @Version: v1.0
 */
@RestController
public class MyController {
    @GetMapping(value = "/test")
    public Object test(){
        return "test";
    }

    @GetMapping(value = "/user")
    @PreAuthorize("hasAnyRole('ROLE_USER')")
    public Object user(){
        return "user";
    }

    @GetMapping(value = "/user/a")
    public Object user2(){
        return "user";
    }

    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    @GetMapping(value = "/admin")
    public Object admin(){
        return "admin";
    }

    @GetMapping(value = "/admin/b")
    public Object admin2(){
        return "admin";
    }
}

总结

小伙伴建议搭建的思路是先搭建 spring boot + spring security,保证你的鉴权是OK,spring boot 1.x版本和2.x版本是有区别的,搭建的时候自行查看文档,那么Oauth的集成速度就很快了,最后说一下。
不建议出问题首先从源码找原因,官网文档和小伙伴的博客可以作为首选,在配合跟踪源码,更容易理解,前人栽的树,你不用多浪费资源

发布了2 篇原创文章 · 获赞 0 · 访问量 13

猜你喜欢

转载自blog.csdn.net/liu__hui2008ooo/article/details/104904137