Spring Security form login 权限认证模式的实例详解编程语言

Spring Security form login 权限认证模式的实例

主要思路

这篇文章算是接着我很早一篇的关于Spring Security的一篇文章写的。算是我对于这个认证机制的个人理解。
Spring Security其核心就是一组过滤器链,项目启动后将会自动配置。在这次的实例中所用的是Usernamepassword的认证模式,
具体认证流程如下
在这里插入图片描述
这个图片中详细的描述了为了验证用户身份所进行的一系列调用,需要用户自己实现的接口便是UserDetailService中的loadUserByName()函数,这个函数需要根据传入的参数Username返回一个UserDetail对象,里面包含着用户名密码权限等诸多信息,而这些信息一般都存储在数据库中,因此我们需要构建实体类User以及数据库操作接口UserService,以及其实现类UserServiceImpl,有了这三个类,我们就可以在userServiceimpl中建立一个可以根据username搜索并返回user对象的函数,而之前说过的UserDetailService中的loadUserByName()函数可以通过调用这个函数将userdetail信息进行返回,从而使得认证过程顺利进行,此外,为了能够对于认证之后的资源开放对象进行管理,我们还需要对于一个配置类进行编辑,即 继承于WebSecurityConfigurerAdapter 的SecurityConfig ,这些都可以算是后端的一些文件,如果想要测试,可以做一些简单的前端测试页面,并设置controller类对页面和路径进行映射。
总结一下上面的全部流程,可以发现需要我们实现的类大致有以下几个:1UserDetailsService,对其loaduserbyusername函数进行编写
2User实体类,实现数据库的映射
3UserService接口,定义数据库操作函数
4 UserServiceImpl实现类,实现上文所述接口的函数
5 Security Config类,用来控制相关资源路径对于不同角色的权限
6contrloller类,用来控制访问路径与实际网页的映射。
注 以上提到的类名并不一定与下文中的完全相同,理解意思即可

详细文件

UserDetailsServiceImp

@Service 
public class UserDetailsServiceImp implements UserDetailsService {
    
    @Autowired 
    private UserDAO userService; 
 
    @Override 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    
        User user = userService.findById(username).get(); 
 
        if (user == null) {
    
            throw new UsernameNotFoundException("用户ID" + username + "未找到"); 
        } 
        JwtUser jwtUser=new JwtUser(user); 
        return jwtUser; 
 
    } 
} 

User

@Entity 
@Table(name="user") 
 
public class User {
    
    @Id 
    @Column(name = "username") 
    private String username; 
    @Column(name = "password") 
    private String password; 
    @Column(name = "role") 
    private String role; 
 
    public void setRole(String role) {
    
        this.role = role; 
    } 
 
    public void setPassword(String password) {
    
        this.password = password; 
    } 
 
    public void setUsername(String username) {
    
        this.username = username; 
    } 
 
    public String getPassword() {
    
        return this.password; 
    } 
 
    public String getRole() {
    
        return this.role; 
    } 
 
    public String getUsername() {
    
        return this.username; 
    } 
} 

将User类进行包装变为UserDetail类的中间类

public class JwtUser implements UserDetails {
    
 
    private String username; 
    private String password; 
    private Collection<? extends GrantedAuthority> authorities; 
 
    // 写一个能直接使用user创建jwtUser的构造器 
    public JwtUser(User user) {
    
        username = user.getUsername(); 
        password = user.getPassword(); 
        authorities = Collections.singleton(new SimpleGrantedAuthority(user.getRole())); 
    } 
 
    @Override 
    public Collection<? extends GrantedAuthority> getAuthorities() {
    
        return authorities; 
    } 
 
    @Override 
    public String getPassword() {
    
        return password; 
    } 
 
    @Override 
    public String getUsername() {
    
        return username; 
    } 
 
    @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 toString() {
    
        return "JwtUser{" + 
                ", username='" + username + '/'' + 
                ", password='" + password + '/'' + 
                ", authorities=" + authorities + 
                '}'; 
    } 
 
} 

UserDAO

public interface UserDAO extends JpaRepository<User,String> {
    
 
} 

这里我并没有自定义其他方法因此并没有写该类的实现类
SecurityConfig

@Configuration 
@EnableWebSecurity(debug=false) 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter {
 
@Resource 
private MyAuthenticationSuccessHandler successHandler; 
@Resource 
private MyAuthenticationFailureHandler failureHandler; 
@Resource 
private UserDetailsService myUserDetailsService; 
@Resource 
private JwtAuthTokenFilter jwtAuthTokenFilter; 
@Bean 
@Override 
public AuthenticationManager authenticationManagerBean() throws Exception 
{
 
return super.authenticationManagerBean(); 
} 
@Override 
protected void configure(HttpSecurity httpSecurity)throws Exception{
 
httpSecurity.formLogin() 
.loginPage("/login.html") 
.loginProcessingUrl("/login") 
.usernameParameter("username") 
.passwordParameter("password") 
//.defaultSuccessUrl("/index") 
//.failureUrl("/login") 
.successHandler(successHandler) 
.failureHandler(failureHandler) 
.and() 
.authorizeRequests() 
.antMatchers("/login","/login.html") 
.permitAll() 
.antMatchers("/system/order","/system/menu") 
.hasAnyAuthority("admin") 
.antMatchers("/system/role") 
.hasAnyAuthority("admin","user") 
//.hasAnyAuthority("ROLE_admin") 
.anyRequest().authenticated() 
.and() 
.csrf().disable(); 
httpSecurity.logout().logoutUrl("/logout"); 
httpSecurity.addFilterBefore(jwtAuthTokenFilter, UsernamePasswordAuthenticationFilter.class); 
} 
@Override 
protected void configure(AuthenticationManagerBuilder auth)throws Exception{
 
auth.userDetailsService(myUserDetailsService) 
.passwordEncoder(bCryptPasswordEncoder()); 
} 
public BCryptPasswordEncoder bCryptPasswordEncoder(){
 
return new BCryptPasswordEncoder(); 
} 
} 

homeController

@Controller 
public class HomeController  {
 
@GetMapping("/index") 
public String index(){
 
return "index"; 
} 
@GetMapping("/system/user") 
public String userList(){
 
return "user"; 
} 
@GetMapping("/system/role") 
public String roleList(){
 
return "role"; 
} 
@GetMapping("/system/menu") 
public String menuList(){
 
return "menu"; 
} 
@GetMapping("/system/order") 
public String orderList(){
 
return "order"; 
} 
} 

相关的网页
login.html

<!DOCTYPE html> 
<html lang="en"> 
<head> 
<meta charset="UTF-8"> 
<title>登陆首页</title> 
<script src="https://cdn.staticfile.org/jquery/1.12.3/jquery.min.js"></script> 
</head> 
<body> 
<h1>实训管理系统</h1> 
<form action="/login" method="post"> 
<span>用户账号</span><input type="txt" name="username" id="username"/><br> 
<span>用户密码</span><input type="password" name="password" id="password"/><br> 
<!--- <input type="submit" value="登录">--> 
<input type="button" onclick="login()" value="登录"> 
<a href="/regist.html">注册</a> 
</form> 
</body> 
<script> 
function login(){
 
$.ajax( 
{
 
type:"POST", 
url:"/login", 
data:{
 
"username":$("#username").val(), 
"password":$("#password").val() 
}, 
success:function(data){
 
if(data.code==200){
 
location.href="/index"; 
}else{
 
alert(data.msg); 
} 
} 
} 
); 
} 
</script> 
</html> 

index.html

<!DOCTYPE html> 
<html xmlns:th="http://www.thymeleaf.org"> 
<head> 
<meta charset="UTF-8"> 
<title>Title</title> 
</head> 
<body> 
</body><head> 
<meta charset="UTF-8"> 
<title>index</title> 
</head> 
<body> 
<h1> 
用户登录 
</h1> 
<br> 
<a href="/system/user"> 
用户管理 
</a> 
<br> 
<a href="/system/menu"> 
目录管理 
</a> 
<br> 
<a href="/system/role"> 
角色管理 
</a> 
<br> 
<a href="/system/order"> 
订单管理 
</a> 
<a href="/logout"> 
退出 
</a> 
</body> 
</html> 

menu.html

<!DOCTYPE html> 
<html xmlns:th="http://www.thymeleaf.org"> 
<head> 
<meta charset="UTF-8"> 
<title>menu</title> 
</head> 
<body> 
<h1>目录页面</h1> 
</body> 
</html> 

剩下的角色页面订单页面也都是只有四个字显示,和这个文件没有什么不同,不在赘述了

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/17784.html

(0)
上一篇 2021年7月19日 20:28
下一篇 2021年7月19日 20:29

相关推荐

发表回复

登录后才能评论