赞
踩
spring security是一个安全可靠且高度可定制的安全框架,它提供身份验证和访问权限控制。按照框架的要求提供相关的信息和配置就可以利用spring security写出企业级安全的登录功能。其核心功能主要如下:
有了springboot之后,springboot对spring security提供了自动化配置的方案,所以在springboot项目中可以实现零配置使用spring security。
在pom.xml文件引入spring security的依赖,(图中是在聚合项目里使用spring security,如果在独立的项目中使用还需要进行版本控制)
引入依赖后再访问你项目的任何资源都会跳转到登录页面,并在idea控制台生成临时密码,此时默认的登录用户是user。
在项目的application.properties文件 中可以配置自定义的用户和密码,不过添加自定义的用户和密码之后,spring就不再提供随机密码,user用户也会作废。为了防止配置文件暴露后所有人都可以看到用户登录信息,可以使用加密算法对密码进行加密操作,这里使用的是bcrypt加密方式。
使用安全框架完成一个简单的登录功能,首先写一个securityConfig配置类(命名可以更改,规范最好使用securityConfig)继承WevSecurityConfigureAdapter类,并重写configure方法,参数为AuthenticationManagerBuilder,顺便授权,具体代码如下:
- //添加@Configuration注解
- @Configuration
- //启动Spring-security配置的注解
- @EnableGlobalMethodSecurity(prePostEnabled = true)
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
- //配置类要继承WebSecurityConfigurerAdapter
-
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- String[] as = {"admin","delete"}; //如果有多个资源的情况下,用数组封装
- auth.inMemoryAuthentication()
- .withUser("用户名")
- .password("{加密方式}加密后的密码字符串")
- .authorities(as);//这里填写需要特殊权限才能访问的资源
- }
-
- }
-
-
-
- //控制器中需要特殊权限才能访问的方法
- public class UserController {
- //@PreAuthorize规定当前控制器方法需要特殊授权才能访问
- //其他控制器方法登录就可以访问
- //添加以下注解指定特殊的权限
- @PreAuthorize("hasAuthority('admin')")
- @GetMapping("/admin")
- public String admin(){
- return "管理";
- }
- @GetMapping("/delete")
- @PreAuthorize("hasAuthority('delete')")
- public String delete(){
- return "删除";
- }
使用spring security 提供的用户和密码或自定义用户和密码在实际开发中是不能满足需求的,所以要想结合项目需求完成实际的登录验证,还需要编写其他代码。spring security将登录的细节封装在内部了,因此我们只需要实现Spring security提供的UserDetailsService接口,在实现类中按照要求重写相关的方法即可。方法的参数就是用户登录时输入的用户名,spring Security会自动为它赋值并返回一个userDetails对象,该对象就包含了用户的登录信息和权限等。
首先在service.impl包下创建一个UserDetailsServiceImpl类,实现UserDetailsService接口,并在该类上添加@service注解。
重写loadUserByUsername方法,这个方法是spring security规定必须实现的方法,方法的参数就是用户登录表单中输入的用户名,利用这个用户名查询其他信息,比如密码和所有权限 最终将这些信息封装到userDetails对象中返回,代码如下:
- @Override
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- //1、根据用户名获取用户对象
- User user = userMapper.findByUsername(username);
- //2、验证用户对象是否为空,如果为空则登录失败
- if(user==null){
- return null;
- }
- //3、根据用户id查询用户的所有权限
- List<Permission> permissions = userMapper.findUserPermissionsById(user.getId());
- //根据用户id查询用户角色
- List<Role> roles = userMapper.findUserRoleById(user.getId());
- //4、将权限List集合转化为String类型的数组
- String[] auth = new String[permissions.size()];
- int i=0;
- for(; i<auth.length; i++){
- auth[i] = permissions.get(i).getName();
- }
- auth = Arrays.copyOf(auth,auth.length+ roles.size());
- for (Role role:roles) {
- auth[i] = role.getName();
- }
- //5、创建UserDetails对象并向他的属性中赋值
- UserDetails details = org.springframework.security.core.userdetails.User
- .builder()
- .username(user.getUsername()) //设置用户名
- .password(user.getPassword()) //设置密码
- .authorities(auth) //设置权限
- .accountLocked(user.getLocked()==1) //设置当前账号是否锁定
- .disabled(user.getEnabled()==0) //设置账户当前账号是否可用
- .build();
- //6、返回UserDetails对象
-
- return details;
- }
以上代码只是我们编写的一个类,还需要把它交给spring security,才能在用户登录的时候调用它根据用户实际输入的用户名完成登录验证。需要在securityConfig中进行如下修改:
- @Autowired //自动装配UserDetailsService
- private UserDetailsService userDetailsService;
-
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- //将UserDetailsService对象指定到Spring-Security框架
- //Spring-Security框架就拿到了UserDetails对象(用户名、密码、权限信息)
- auth.userDetailsService(userDetailsService);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。