项目之用户登录和访问权限的控制(5)

简介: 项目之用户登录和访问权限的控制(5)

13. 用户登录-准备工作


在开发注册功能时,在SecurityConfig类中配置以如下代码:


@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();
}

以上代码的作用是关闭跨域攻击,如果没有以上代码,则执行异步请求时就会出错!


一旦添加了以上代码,却没有添加更多详细配置之前,Spring Security的登录拦截将不生效!为了便于开发登录功能,先暂时将以上代码去除(删除,或添加为注释)。


另外,在SecurityConfig中还有:


@Bean

public PasswordEncoder passwordEncoder() {

   return new BCryptPasswordEncoder();

}


以上代码的作用是创建密码加密器对象并交给Spring容器进行管理,以至于需要执行密码加密时,直接自动装配密码加密器即可!


目前,为了保证能够正确登录,需要将以上密码加密器去除,因为,开发完注册功能后,用户注册成功后的密码已经使用密文的形式存储在数据库中了,并且添加了{bcrypt}前缀用于声明加密时使用的算法,Spring Security会自动使用以上代码装配的PasswordEncoder执行1次加密,还会再因为{bcrypt}前缀再执行1次加密,就会导致登录验证失败!


【小结】密文使用${bcrypt}前缀,和让Spring容器管理BcryptPasswordEncoder这2个做法只能二选一!

一旦去除以上代码,就会导致Spring容器中没有PasswordEncoder对象了,但是,在UserServiceImpl中还需要使用到它,则应该将其调整为自行创建的模式,即:


// @Autowired // 需要去除自动装配注解

PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();


14. 用户登录-基于内存验证的模拟登录


先将application.properties中配置的Spring Security的用户名和密码去除!


然后,在SecurityConfig类(继承自WebSecurityConfigurerAdapter的配置类)中重写protected void configure(AuthenticationManagerBuilder auth)方法,并在这个方法中配置允许使用的用户名、密码及该账号的权限:


@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("java")
            .password("{bcrypt}$2a$10$tsM03ULkiifEpSCWtQ5Mq.yrLZIPKVr5vHwU1FGjtT9B1vPlswa.C")
            .authorities("/test");
}


以上密文密码的原文是1234。

注意:配置以上代码时,必须调用authorities()以配置授权范围,如果没有配置,将会启动失败,由于当前尚未配置各请求所需要具备的权限,所以,关于以上范围,可以暂时使用任意字符串表示。


15. 用户登录-UserDetailsService接口


Spring Security定义了UserDetailsService接口,在接口存在抽象方法:


UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;


该方法的作用是:给定用户名,需要返回用户详情(UserDetails类型的对象),Spring Security获取到该用户详情后,会自动完成用户身份的验证,包括验证成功之后的用户权限信息,都是由框架处理的,作为开发人员,只需要解决“根据用户名获取用户详情”的问题即可!


可以在cn.tedu.straw.portal.security包中创建UserDetailsServiceImpl类,实现以上接口,模拟实现获取用户数据:

@Component
public class UserDetailsServiceImpl implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 假设正确的用户名是security
        // 假设用户名是正确值:security
        if ("security".equals(username)) {
            // 通过Spring-Security提供的User类来构建UserDetails对象
            UserDetails userDetails = User.builder()
                    .username("security")
                    .password("{bcrypt}$2a$10$tsM03ULkiifEpSCWtQ5Mq.yrLZIPKVr5vHwU1FGjtT9B1vPlswa.C")
                    .authorities("test")
                    .build();
            return userDetails;
        }
        return null;
    }
}



注意:以上类必须在组件扫描的包中,并添加@Component注解,则Spring框架会自动创建以上类的对象并管理,后续就可以直接装配这个类的对象了!


然后,回到SecurityConfig类,应用以上类的对象:


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


注意:以上全局属性声明为UserDetailsServiceImpl类型,不可以声明为其接口类型,因为接口类型的对象不只1个。


16. 用户登录-查询数据库验证登录


先在IUserService接口中添加抽象方法:


UserDetails login(String username);


严格意义上来说,以上方法并不是“登录”方法,只是一个“获取用户详情”的方法,甚至都不知道登录成功与否,所以,在参数列表中也没有密码,后续,将由Spring Security获取以上方法返回的对象,并验证密码是否正确等。

然后,在UserServiceImpl实现类中重写以上抽象方法:

@Override
public UserDetails login(String username) {
    // 根据参数username查询用户信息
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("username", username);
    User user = userMapper.selectOne(queryWrapper);
    // 判断查询结果是否为null,即:有没有这个用户
    // 注意:后续的验证和最终的界面是由Spring-Security显示的,此处不要抛出异常
    if (user == null) {
        return null;
    }
    // 组织“用户详情”对象
    // TODO 未完
    UserDetails userDetails = org.springframework.security.core.userdetails.User
            .builder()
            .username(user.getUsername())
            .password(user.getPassword())
            .authorities("test")
            .build();
    return userDetails;
}
目录
相关文章
|
9月前
|
数据安全/隐私保护
fastadmin是如何设置没有权限的用户不能访问某些页面的?
fastadmin是如何设置没有权限的用户不能访问某些页面的?
247 0
|
3天前
|
存储 安全 Android开发
Android系统 AppOps默认授予应用相应的权限
Android系统 AppOps默认授予应用相应的权限
6 0
|
6月前
|
安全 数据库 数据安全/隐私保护
什么是特权账号,如何定义
对特权账号进行简单定义,区别普通账号
56 0
什么是特权账号,如何定义
|
6月前
|
UED
路由权限登录后还保留上一个登录角色的权限,刷新一下就好了的解决方案
路由权限登录后还保留上一个登录角色的权限,刷新一下就好了的解决方案
31 0
|
6月前
|
资源调度 前端开发 数据库
权限 | 前端控制权限
啊,我们经常做权限控制,控制菜单,控制按钮功能等,但是在一些特殊情况下不能够由后端来做权限控制,那就只能前端来做啦。
|
中间件 数据安全/隐私保护
使用RoleBasedAuthorization实现基于用户角色的访问权限控制
本文将介绍如何通过 [Sang.AspNetCore.RoleBasedAuthorization](https://www.nuget.org/packages/Sang.AspNetCore.RoleBasedAuthorization) 库实现 RBAC 权限管理。
141 0
使用RoleBasedAuthorization实现基于用户角色的访问权限控制
|
安全 Java 测试技术
项目之用户登录和访问权限的控制(6)
项目之用户登录和访问权限的控制(6)
238 0
|
数据安全/隐私保护
【自然框架】之通用权限的Demo(二):添加人员、添加账户、添加角色里面的账户以及列表的权限验证
      看了一下上一次发Demo的日期6月15日,已经过了半个多月,这个速度也实在是太慢了。还是心情的原因,恩,心理承受能力太弱了,哈哈。不过还是要坚持的,要继续下去。       还是先说一下这次的Demo里增加的内容吧。
838 0