全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Spring Boot中整合Spring Security并自定义验证代码实例

最终效果

1、实现页面访问权限限制
2、用户角色区分,并按照角色区分页面权限
3、实现在数据库中存储用户信息以及角色信息
4、自定义验证代码

效果如下:

1、免验证页面

 

2、登陆页面

在用户未登录时,访问任意有权限要求的页面都会自动跳转到登陆页面。

 

3、需登陆才能查看的页面

用户登陆后,可以正常访问页面资源,同时可以正确显示用户登录名:

 

4、用户有角色区分,可以指定部分页面只允许有相应用户角色的人使用

4.1、只有ADMIN觉得用户才能查看的页面(权限不足)

 

4.2、只有ADMIN觉得用户才能查看的页面(权限满足)

以下具体说明实现步骤。

代码实现

MAVEN引入依赖

在pom.xml中引入spring security依赖

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

配置Spring Security

在Spring中,配置和使用Spring Security,在不需要修改太多流程细节的情况下仅需声明好拦截规则,同时自定义验证过程中的主要实现接口(用户信息UserDetails,用户信息获取服务UserDetailsService,验证工具AuthenticationProvider)即可。其余的流程将由Spring自动接管,非常方便。

启动配置

在项目包下添加WebSecurityConfigurerAdapter 的具体实现类,实现Spring Security的启动配置

代码如下:

@Configurable
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)//允许进入页面方法前检验
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired
  private MyAuthenticationProvider provider;//自定义验证
  @Autowired
  private UserDetailsService userDetailsService;//自定义用户服务
  @Autowired
  public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception{
  }


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

    .antMatchers(StaticParams.PATHREGX.NOAUTH, 
        StaticParams.PATHREGX.CSS,StaticParams.PATHREGX.JS,StaticParams.PATHREGX.IMG).permitAll()//无需访问权限

    .antMatchers(StaticParams.PATHREGX.AUTHADMIN).hasAuthority(StaticParams.USERROLE.ROLE_ADMIN)//admin角色访问权限

    .antMatchers(StaticParams.PATHREGX.AUTHUSER).hasAuthority(StaticParams.USERROLE.ROLE_USER)//user角色访问权限

    .anyRequest()//all others request authentication
    .authenticated()
    .and()
    .formLogin().loginPage("/login").permitAll()
    .and()
    .logout().permitAll();
  }

  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    //将验证过程交给自定义验证工具
    auth.authenticationProvider(provider);
  }

URL拦截配置

URL拦截配置可以在上一小节的WebSecurityConfig 中配置,但是此方法适用于大方向上的配置,具体的特殊路径也可以在@Controller的注解中具体配置。

如下:

  @ResponseBody
  @PreAuthorize("hasAuthority('"+StaticParams.USERROLE.ROLE_ADMIN+"')")//这里可以指定特定角色的用户访问权限
  @RequestMapping(value = "adminrequire", method = RequestMethod.GET)
  public String adminrequire(){
    return "HELLO from web but you should be admin";
  }

用户、角色表

在本文例子中用户和角色可以有一对多的关系因此可以将用户和角色分成两张表。有些例子将用户和权限写在同一张表上也是可以的。

/*用户表*/
@Entity
@Table(name = "user")
public class SystemUser {

  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  private String userName;
  private String password;

  public SystemUser(){}

  public SystemUser(SystemUser user){
    this.userName = user.getUserName();
    this.password = user.getPassword();
    this.id = user.getId();
  }

  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }
  public String getUserName() {
    return userName;
  }
  public void setUserName(String userName) {
    this.userName = userName;
  }
  public String getPassword() {
    return password;
  }
  public void setPassword(String password) {
    this.password = password;
  }
}
/*角色表*/
@Entity
@Table(name = "user_role")
public class UserRole {

  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;

  private String role;
  private Long userId;
  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }
  public String getRole() {
    return role;
  }
  public void setRole(String role) {
    this.role = role;
  }
  public Long getUserId() {
    return userId;
  }
  public void setUserId(Long userId) {
    this.userId = userId;
  }
}



自定义验证

在Spring Boot的Spring Security的教程中默认的用户名、密码、权限是在代码中指定的

@Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
      .inMemoryAuthentication()
        .withUser("user").password("password").roles("USER");
  }

这显然是不符合应用需求的,所以我们需要提供自定义的AuthenticationProvider,并在上边代码中替换即可。在此之前,我们应该重写获取用户User和权限的方法。通过查询相关资料和API,方法提供如下:

自定义UserDetails

UserDetails代表了Spring Security的用户认证实体,带有用户名、密码、权限列表、过期特性等性质,可以自己声明类实现UserDetails接口,如果不想自己声明,也可以用SpringSecurity的默认实现org.springframework.security.core.userdetails.User 本文例子中采用自定义类:

public class MyUserDetails extends SystemUser implements UserDetails{

  private List<UserRole> roles;

  public MyUserDetails(SystemUser user, List<UserRole> roles){
    super(user);
    this.roles = roles;
  }

  @Override
  public Collection<? extends GrantedAuthority> getAuthorities() {
    if(roles == null || roles.size() <1){
      return AuthorityUtils.commaSeparatedStringToAuthorityList("");
    }
    StringBuilder commaBuilder = new StringBuilder();
    for(UserRole role : roles){
      commaBuilder.append(role.getRole()).append(",");
    }
    String authorities = commaBuilder.substring(0,commaBuilder.length()-1);
    return AuthorityUtils.commaSeparatedStringToAuthorityList(authorities);
  }

  @Override
  public String getPassword() {
    return super.getPassword();
  }

  @Override
  public String getUsername() {
    return super.getUserName();
  }

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

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

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

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

}

自定义UserDetailsService

UserDetailsService提供了获取UserDetails的方式,只要实现UserDetailsService接口即可,最终生成用户和权限共同组成的UserDetails,在这里就可以实现从自定义的数据源中获取用户信息了:

@Service("MyUserDetailsImpl")
public class MyUserDetailsService implements UserDetailsService {
  @Resource(name = "SystemUserServiceImpl")
  private SystemUserService systemUserService;

  @Resource(name = "UserRoleServiceImpl")
  private UserRoleService userRoleService;

  @Override
  public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
    SystemUser user;
    try {
      user = systemUserService.findByName(userName);
    } catch (Exception e) {
      throw new UsernameNotFoundException("user select fail");
    }
    if(user == null){
      throw new UsernameNotFoundException("no user found");
    } else {
      try {
        List<UserRole> roles = userRoleService.getRoleByUser(user);
        return new MyUserDetails(user, roles);
      } catch (Exception e) {
        throw new UsernameNotFoundException("user role select fail");
      }
    }
  }
}

自定义AuthenticationProvider

AuthenticationProvider 提供用户UserDetails的具体验证方式,在这里可以自定义用户密码的加密、验证方式等等。因为博文主要讲的是如何引入Spring Security和如何自定义验证代码,所以这里为了简便,我直接采用明文比较方式:

@Component
public class MyAuthenticationProvider implements AuthenticationProvider {

  @Autowired
  private MyUserDetailsService userService;

  /**
   * 自定义验证方式
   */
  @Override
  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String username = authentication.getName();
    String password = (String) authentication.getCredentials();
    MyUserDetails user = (MyUserDetails) userService.loadUserByUsername(username);
    if(user == null){
      throw new BadCredentialsException("Username not found.");
    }

    //加密过程在这里体现
    if (!password.equals(user.getPassword())) {
      throw new BadCredentialsException("Wrong password.");
    }

    Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
    return new UsernamePasswordAuthenticationToken(user, password, authorities);
  }

  @Override
  public boolean supports(Class<?> arg0) {
    return true;
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# spring  # boot  # security  # springboot和security  # springboot  # security4  # SpringBoot Security权限控制自定义failureHandler实例  # SpringBoot Security的自定义异常处理  # spring boot security自定义认证的代码示例  # 自定义  # 在这里  # 访问权限  # 的人  # 是在  # 太多  # 在此  # 不需要  # 可以用  # 并在  # 上一  # 重写  # 相关资料  # 不符合  # 两张  # 我们应该  # 将由  # 写在  # 数据库中  # 用户登陆 


相关文章: 建站之星CMS五站合一模板配置与SEO优化指南  建站之星2.7模板快速切换与批量管理功能操作指南  建站之星如何助力网站排名飙升?揭秘高效技巧  建站之星IIS配置教程:代码生成技巧与站点搭建指南  网站制作公司广州有几家,广州尚艺美发学校网站是多少?  建站之星后台密码遗忘如何找回?  如何在阿里云虚拟服务器快速搭建网站?  如何解决ASP生成WAP建站中文乱码问题?  建站主机选择指南:服务器配置与SEO优化实战技巧  如何配置支付宝与微信支付功能?  南京网站制作费用,南京远驱官方网站?  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  建站主机解析:虚拟主机配置与服务器选择指南  行程制作网站有哪些,第三方机票电子行程单怎么开?  教学论文网站制作软件有哪些,写论文用什么软件 ?  网站代码制作软件有哪些,如何生成自己网站的代码?  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  开心动漫网站制作软件下载,十分开心动画为何停播?  建站之星安装需要哪些步骤及注意事项?  如何选择香港主机高效搭建外贸独立站?  制作网站的网址是什么,请问后缀为.com和.com.cn还有.cn的这三种网站是分别是什么类型的网站?  北京网站制作公司哪家好一点,北京租房网站有哪些?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  Java解压缩zip - 解压缩多个文件或文件夹实例  ,购物网站怎么盈利呢?  C#如何使用XPathNavigator高效查询XML  最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?  专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?  如何在橙子建站上传落地页?操作指南详解  沈阳制作网站公司排名,沈阳装饰协会官方网站?  高性能网站服务器配置指南:安全稳定与高效建站核心方案  个人摄影网站制作流程,摄影爱好者都去什么网站?  贸易公司网站制作流程,出口贸易网站设计怎么做?  建站之星北京办公室:智能建站系统与小程序生成方案解析  网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?  电商网站制作公司有哪些,1688网是什么意思?  佛山网站制作系统,佛山企业变更地址网上办理步骤?  上海网站制作开发公司,上海买房比较好的网站有哪些?  英语简历制作免费网站推荐,如何将简历翻译成英文?  如何在云主机快速搭建网站站点?  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  盐城做公司网站,江苏电子版退休证办理流程?  北京网站制作网页,网站升级改版需要多久?  如何配置FTP站点权限与安全设置?  如何快速搭建虚拟主机网站?新手必看指南  建站主机是否等同于虚拟主机?  nginx修改上传文件大小限制的方法  魔毅自助建站系统:模板定制与SEO优化一键生成指南  建站主机选哪家性价比最高?  在线制作视频的网站有哪些,电脑如何制作视频短片? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。