资讯专栏INFORMATION COLUMN

Spring Boot [集成-Spring Security]

hedzr / 876人阅读

摘要:导读在上一篇文章中对集成做了一个简单的介绍,这篇文章中主要围绕集成展开文章末尾附有学习资料。当我们使用元素来定义一个时,如果没有指定对应关联的对象,默认会使用。在进行认证的时候需要一个来获取用户的信息,其中包括用户名密码和所拥有的权限等。

导读

在上一篇文章中对Spring Boot 集成Shrio做了一个简单的介绍,这篇文章中主要围绕Spring Boot 集成 Spring Security展开,文章末尾附有学习资料。

快速上手: 1.引入pom依赖

    org.springframework.boot
    spring-boot-starter-security

2.实现一个简单的用户权限类

用户权限功能的设计不是本篇文章的重点,这里以一个简单的例子作为演示,需要创建两个实体类一个枚举类

用户类:

@JsonIgnoreProperties(value = { "hibernateLazyInitializer","password" ,"new"})
@DynamicUpdate
@Entity
public class User extends AbstractPersistable {

    private static final long serialVersionUID = 2080627010755280022L;

    private String userName;

    @Column(unique = true, updatable = false)
    private String loginName;


    private String password;
    

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set roles;

    /**省略get/set**/
}

角色类别:

public enum RoleType {

    //級別从高到低 ADMIN->USER
    ADMIN,//管理员 

    USER//普通用户
}

角色类:

@Entity
public class Role extends AbstractPersistable {

    private static final long serialVersionUID = -856234002396786101L;

    @Enumerated(EnumType.STRING)
    @Column(name = "role_name", unique = true)
    private RoleType roleType;
}
3.定制自己的配置

首先需要从数据库中查询出来用户数据交给Spring Security这里有两种主要的方式:

AuthenticationProvider&&UserDetailsService两种方式的介绍:

Spring Security认证是由 AuthenticationManager 来管理的,但是真正进行认证的是 AuthenticationManager 中定义的 AuthenticationProvider。AuthenticationManager 中可以定义有多个 AuthenticationProvider。当我们使用 authentication-provider 元素来定义一个 AuthenticationProvider 时,如果没有指定对应关联的 AuthenticationProvider 对象,Spring Security 默认会使用 DaoAuthenticationProvider。DaoAuthenticationProvider 在进行认证的时候需要一个 UserDetailsService 来获取用户的信息 UserDetails,其中包括用户名、密码和所拥有的权限等。所以如果我们需要改变认证的方式,我们可以实现自己的 AuthenticationProvider;如果需要改变认证的用户信息来源,我们可以实现 UserDetailsService。

a.实现UserDetailsService 接口
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByLoginName(username);
        if(user == null){
            throw new UsernameNotFoundException("not found");
        }
        List authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority(user.getRole().name()));
        System.err.println("username is " + username + ", " + user.getRole().name());
        return new org.springframework.security.core.userdetails.User(user.getUsername(),
                user.getPassword(), authorities);
    }

}

将自己的配置托管给Sprng 管理,Security为我们提供了WebSecurityConfigurerAdapter 我们只需要根据自己的需要进行继承重写即可

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    @Bean
    public UserDetailsService userDetailsService() {
        return new CustomUserDetailsService();
    }

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/index").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/admin")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

}
b.实现 AuthenticationProvider接口
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    private static final Logger logger = LoggerFactory.getLogger(CustomAuthenticationProvider.class);
   

    @Autowired
    private UserRepository userRepository;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String loginName = authentication.getName();
        String password = authentication.getCredentials().toString();
        List grantedAuths = new ArrayList<>();
        if (vaildateUser(loginName, password, grantedAuths)) {
            Authentication auth = new UsernamePasswordAuthenticationToken(loginName, password, grantedAuths);
            return auth;
        } else {
            return null;
        }
    }

    public boolean vaildateUser(String loginName, String password, List grantedAuths) {
        User user = userRepository.findByLoginName(loginName);
        if (user == null || loginName == null || password == null) {
            return false;
        }
        if (user.getPassword().equals(SHA.getResult(password)) && user.getUserStatus().equals(UserStatus.NORMAL)) {
            Set roles = user.getRoles();
            if (roles.isEmpty()) {
                grantedAuths.add(new SimpleGrantedAuthority(RoleType.USER.name()));
            }
            for (Role role : roles) {
                grantedAuths.add(new SimpleGrantedAuthority(role.getRoleType().name()));
                logger.debug("username is " + loginName + ", " + role.getRoleType().name());
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean supports(Class authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

将配置托管给Spring

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;
    

    @Override  
    protected void configure(AuthenticationManagerBuilder auth)  
            throws Exception {   
        auth.authenticationProvider(customAuthenticationProvider);
    }  

    @Override
    protected void configure(HttpSecurity http) throws Exception {
         http
            .authorizeRequests()
                .antMatchers("/", "/index").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/admin")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

}
4.添加角色验证

我们将用户分成了管理员与普通用户,用户页面对用户与管理可见,管理员页面只对管理员可见

@Controller
public class UserController {

    PreAuthorize("hasAnyAuthority("ADMIN","USER")")
    @GetMapping("/user")
    public String user(){
        return "user";
    }
    
    @PreAuthorize("hasAnyAuthority("ADMIN")")@
    @GetMapping("/admin")
    public String admin(){
        return "admin";
    }
}       

Spring Security虽然要比Apache Shiro功能强大,但作为Spring 自家的应用与Spring 整合确实非常简单,同样Spring Security 学习成本要比Apache Shiro高。

结语

这篇文章是匆忙中挤时间赶工出来的产物,有些地方也许写的有些问题,欢迎提出反馈。下篇文章打算用之前所学的技术做一个简单的项目,正在想做什么,欢迎提出建议。

学习资料:

Spring Security 中文参考手册
Spring Security系列博客

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66915.html

相关文章

  • 《 Kotlin + Spring Boot : 下一代 Java 服务端开发 》

    摘要:下一代服务端开发下一代服务端开发第部门快速开始第章快速开始环境准备,,快速上手实现一个第章企业级服务开发从到语言的缺点发展历程的缺点为什么是产生的背景解决了哪些问题为什么是的发展历程容器的配置地狱是什么从到下一代企业级服务开发在移动开发领域 《 Kotlin + Spring Boot : 下一代 Java 服务端开发 》 Kotlin + Spring Boot : 下一代 Java...

    springDevBird 评论0 收藏0
  • Spring Boot Admin 2.1.0 全攻略

    摘要:并向注册中心注册,注册地址为,最后将的所有端口暴露出来,配置如下在工程的启动类加上注解,开启的功能,加上注解开启的功能。在启动类加上注解,开启的功能。 转载请标明出处: https://www.fangzhipeng.com本文出自方志朋的博客 Spring Boot Admin简介 Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序。 ...

    TalkingData 评论0 收藏0
  • Spring Security

    摘要:框架具有轻便,开源的优点,所以本译见构建用户管理微服务五使用令牌和来实现身份验证往期译见系列文章在账号分享中持续连载,敬请查看在往期译见系列的文章中,我们已经建立了业务逻辑数据访问层和前端控制器但是忽略了对身份进行验证。 重拾后端之Spring Boot(四):使用JWT和Spring Security保护REST API 重拾后端之Spring Boot(一):REST API的搭建...

    keelii 评论0 收藏0
  • ApiBoot - ApiBoot Security Oauth 依赖使用文档

    摘要:如果全部使用默认值的情况话不需要做任何配置方式前提项目需要添加数据源依赖。获取通过获取启用在使用格式化时非常简单的,配置如下所示开启转换转换时所需加密,默认为恒宇少年于起宇默认不启用,签名建议进行更换。 ApiBoot是一款基于SpringBoot1.x,2.x的接口服务集成基础框架, 内部提供了框架的封装集成、使用扩展、自动化完成配置,让接口开发者可以选着性完成开箱即...

    Tonny 评论0 收藏0
  • SpringCloud打造微服务平台--概览

    摘要:授权框架使第三方应用程序来获取对服务的有限访问机会。无论是通过编排资源所有者和服务之间的交互批准的资源所有者,或通过允许第三方应用程序来获取自己的访问权限。 SpringCloud打造微服务平台--概览 简述 SpringCloud是什么 Spring Boot和SpringCloud是什么关系 Spring Boot是Spring的一套快速WEB开发的脚手架,可建立独立的Sprin...

    siberiawolf 评论0 收藏0

发表评论

0条评论

hedzr

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<