原创文章转载请注明来源:https://blog.csdn.net/weixin_41756573/article/details/89060081
初次接触spring security,写的不好,也许还会有效bug,请多指教,欢迎留言。持续更新中
项目的目录结构
1.完整的pom.xml
2.启动类
package com.system.security;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.system.security.mapper") // 整合mybatis
public class SpringbootSecurity {
public static void main(String[] args) {
SpringApplication.run(SpringbootSecurity.class, args);
}
}
3.class WebSecurityConfiguration extends WebSecurityConfigurerAdapter(重点)
作用:是对spring security的整体配置,主要是关于登录验证和资源访问的配置
package com.system.security.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/***
* spring security 安全配置中心
* @author BAIAYANG
* @Time 2019.4.1
*/
@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
/**
* 配置密码的加密与解密
* @return 返回加密的方式(比如MD5,BCryptPasswordEncoder:security自带的加密方式等)
*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 对spring security 的配置
* 拦截url
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin() //使用表单登录
.loginPage("/login.html") // 指向登录页面,或者是路由(注意/)
.loginProcessingUrl("/user_login") // 通知UsernamePasswordAuthenticationFilter该路径是处理登录请求的路径
.and()
.authorizeRequests() //授权操作
.antMatchers("/login.html").permitAll() // permitAll 任何身份均可以访问
.antMatchers("/user_info").hasRole("ADMIN") // hasRole 只有拥有该角色的人才可以访问;.antMatchers(HttpMethod.GET,"/user_info/*"),第一个参数指定方法的请求方式,通配路径
.anyRequest() // 任何请求
.authenticated() // 需要身份认证
.and()
.csrf().disable(); // 关闭跨站请求防护
}
/**
* 取消对静态资源的拦截
*/
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**","/css/**","/images/**");//对于这些静态文件,忽略拦截
}
}
重点一:搭建用户登录验证的功能
1.spring security 的 UserDetails
2.spring security 的 UserDetailsService
3.spring security 的 PasswordEncode
我对UserDetails的理解
作用:封装登录的用户信息,为用户是否可以登录做准备
package com.system.security.entity;
import java.util.Collection;
import java.util.List;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
public class MyUserDetails extends User implements UserDetails {
private static final long serialVersionUID = -5851249649932993238L;
/**
* 该用户所有角色的集合
*/
private List
/**
* 通过构造函数将User对象注入以及该用户的所有角色
*/
public MyUserDetails(User user,List
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(Role role : roles){
commaBuilder.append("ROLE_"+role.getName()).append(",");
}
String authorities = commaBuilder.substring(0,commaBuilder.length()-1);
return AuthorityUtils.commaSeparatedStringToAuthorityList(authorities);
}
/**
* 账号是否过期
*/
@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的理解
作用:查询用户以及角色信息,将信息封装为UserDetails传递给spring security,做出判断
package com.system.security.service.impl;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.system.security.entity.MyUserDetails;
import com.system.security.entity.Role;
import com.system.security.entity.User;
import com.system.security.mapper.RoleUserMapper;
import com.system.security.mapper.UserMapper;
/***
* 处理用户登录的请求
* @author BAIYANG
*
*/
@Service
public class MyUserDetailsService implements UserDetailsService {
@Resource
private UserMapper userMapper;
@Resource
private RoleUserMapper roleUserMapper;
/**
* 通过用户名获取一个UserDetails对象
* 和你在filter配置的做比较
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//1.根据用户名查询用户信息
User user = userMapper.findByUserName(username);
if(user==null) {
throw new UsernameNotFoundException(username);
}else{
//2.查询该用户的角色信息
List
//3.将用户信息封装为一个UserDetails
return new MyUserDetails(user, roles);
// 模拟,注意密码的解密new BCryptPasswordEncoder().encode()注册时完成的加密,实际开发中直接将密码封装到这里即可
//return new User(username, new BCryptPasswordEncoder().encode("123456"), //AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
/**
* org.springframework.security.core.userdetails.User.User(String username, String password, Collection extends GrantedAuthority> authorities)
* username 用户名
* password 密码
* authorities 权限的集合
*/
}
}
}