springboot集成springsecurity
配置springsecurity的config类
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
/**
* 认证
* <p>
* 重写configure(AuthenticationManagerBuilder auth)方法来配置认证方式,
* 在auth.userDetailsService()方法中传入userService,userDetailsService()方法在用户登录时将会被自动调用。
* passwordEncoder是可选项,可写可不写,因为我是将用户的明文密码生成了MD5消息摘要后存入数据库的,
* 因此在登录时也需要对明文密码进行处理,所以就加上了passwordEncoder,加上passwordEncoder后,
* 直接new一个PasswordEncoder匿名内部类即可,这里有两个方法要实现,看名字就知道方法的含义,
* 第一个方法encode显然是对明文进行加密,这里使用MD5消息摘要,具体的实现方法是由commons-codec依赖提供的,
* 第二个方法matches是密码的比对,两个参数,第一个参数是明文密码,
* 第二个是密文,这里只需要对明文加密后和密文比较即可
*
* @param auth AuthenticationManagerBuilder
* @throws Exception 异常
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new PasswordEncoder() {
/**
* @param charSequence 明文
* @return 密文
*/
@Override
public String encode(CharSequence charSequence) {
return DigestUtils.md5DigestAsHex(charSequence.toString().getBytes());
}
/**
* @param charSequence 明文
* @param s 密文
* @return boolean
*/
@Override
public boolean matches(CharSequence charSequence, String s) {
return s.equals(DigestUtils.md5DigestAsHex(charSequence.toString().getBytes()));
}
});
}
/**
* 授权
* <p>
* 重写configure(HttpSecurity http)方法配置授权规则。
* authorizeRequests()方法表示开启了认证规则配置。
* antMatchers("/admin/**").hasRole("超级管理员")表示/admin/**的路径需要有‘超级管理员’角色的用户才能访问。
* 网上有人对hasRole方法中要不要加ROLE_前缀有疑问,这里是不要加的,如果用hasAuthority方法才需要加。
* anyRequest().authenticated()表示其他所有路径都是需要认证/登录后才能访问。
* login_page为去往登录界面的请求,登录处理路径为/login,登录用户名为username,密码为password,并配置了这些路径都可以直接访问,注销登陆也可以直接访问,最后关闭csrf。
* 在successHandler中,使用response返回登录成功的json即可,切记不可以使用defaultSuccessUrl。
* defaultSuccessUrl是只登录成功后重定向的页面,使用failureHandler也是由于相同的原因。
* @param http HttpSecurity对象
* @throws Exception 异常
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable();
http.authorizeRequests()
.antMatchers("/static/**").permitAll()
//登录界面的路径,所有用户可以访问
.antMatchers("/admin/**").hasRole("manager")
// /admin/**的路径需要有‘超级管理员’角色的用户才能访问
.antMatchers("/user/**").hasRole("productor")
//所有请求需要登录认证
.anyRequest().authenticated()
.and()
// 设置自定义登录的页面
.formLogin().loginPage("/")
// 登录页表单提交的 action 及对应参数名字
.loginProcessingUrl("/produtorcheck/productorlogin").usernameParameter("account").passwordParameter("passWord").permitAll()
//登录成功后做什么
.successHandler(new AuthenticationSuccessHandler() {
/**
* @param httpServletRequest 对象
* @param httpServletResponse 对象
* @param authentication 对象
* @throws IOException 对象
* @throws ServletException 对象
*/
@Override
public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
String str=String.valueOf(SecurityContextHolder.getContext().getAuthentication().getAuthorities());
System.out.println("onAuthenticationSuccess...");
if(str.equals("[ROLE_manager]")){
httpServletResponse.sendRedirect("/manager/test1");
}else{
httpServletResponse.sendRedirect("/productor/test2");
}
}
})
//登录失败后做什么
.failureHandler(new AuthenticationFailureHandler() {
/**
* @param httpServletRequest 对象
* @param httpServletResponse 对象
* @param e 对象
* @throws IOException 对象
* @throws ServletException 对象
*/
@Override
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
System.out.println("onAuthenticationFailure...");
httpServletResponse.sendRedirect("/");
}
})
.and()
//注销功能,注销成功跳转登录页
.logout().logoutSuccessUrl("/").permitAll()
.and()
//关闭跨站检测
.cors().
and()
.csrf().disable();
}
/**
* 过滤
* <p>
* 重写configure(WebSecurity web)方法用来配置过滤规则
* @param web WebSecurity对象
* @throws Exception 异常
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/static/js/**/**.js")
.antMatchers("/static/css/**/**.css")
.antMatchers("/static/images/**/**");
}
}
MyUserDetails类
UserInfo是用户对象类
public class MyUserDetails extends UserInfo implements UserDetails {
private static final long serialVersionUID = 1L;
private String role;
public MyUserDetails(UserInfo userInfo) {
super(userInfo.getId(),userInfo.getUserAccount(),userInfo.getUserPwd(),userInfo.getUserName(),userInfo.getUserAddr(),userInfo.getUserPhone(),userInfo.getUserRole());
role=userInfo.getUserRole();
}
public MyUserDetails(Integer id, String userAccount, String userPwd, String userName, String userAddr, String userPhone, String userRole) {
super(id, userAccount, userPwd,userName,userAddr,userPhone,userRole);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return AuthorityUtils.commaSeparatedStringToAuthorityList(role);
}
@Override
public String getPassword() {
return super.getUserPwd();
}
@Override
public String getUsername() {
return super.getUserAccount();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
UserDetailsServiceImpl类
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
private final UserInfoService userService;
public UserDetailsServiceImpl(UserInfoServiceImpl userService) {
this.userService = userService;
}
@Override
public UserDetails loadUserByUsername(String vendor_account) throws UsernameNotFoundException {
UserInfo userInfo = userService.getByAccount(vendor_account);
if (userInfo == null) {
//避免返回null,这里返回一个不含有任何值的User对象,在后期的密码比对过程中一样会验证失败
return null;
// return new UserInfo();
}
return new MyUserDetails(userInfo);
}
}

浙公网安备 33010602011771号