springboot+springsecurity基于角色的权限验证(二)

采用springboot+springsecurity

用户实体类

public class T_user implements UserDetails {
	private String username;
	private String password;
    //  ... 省略get,set 方法
    @Override
	public String toString() {
		return this.username;
	}
	@Override
	public int hashCode() {
		return username.hashCode();
	}
	
	@Override
	public boolean equals(Object obj) {
		return this.toString().equals(obj.toString());
	}

	// 权限
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		List<GrantedAuthority> grantedAuthority = new ArrayList<> ();
		if (roles != null && roles.size() > 0) {
			for (T_role role : roles) {
				grantedAuthority.add(new SimpleGrantedAuthority(role.getName()));
			}
		}
		
		return grantedAuthority;
	}

	// 账号是否过期
	@Override
	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	// 账号是否锁定
	@Override
	public boolean isAccountNonLocked() {
		// TODO Auto-generated method stub
		return true;
	}

	// 密码是否过期
	@Override
	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}

	// 账号是否可用
	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}
}

登录认证实现类

@Service
public class UserServiceImpl implements UserDetailsService  {

	@Autowired
	private UserMapper userMapper;
	@Autowired
    private SessionRegistry sessionRegistry;
	//@Autowired
	//private PasswordEncoder passwordEncoder;
	@Autowired
	private MD5PasswordEncoder md5PasswordEncoder;

	/**
	 * 重写springSecurity类方法
	 */
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// 通过用户名称获取对象
		T_user user = userMapper.findByUserName(username);
		
		if (user != null) {			
			// 因为角色的添加已经在用户实体类中加入了,所以查询到用户不为空,直接返回用户对象就可以了
			// 123 模拟加密盐
			user.setPassword(md5PasswordEncoder.encode(user.getPassword()+"123"));
			
			return user;
		} else {
			throw new UsernameNotFoundException("admin: " + username + " 不存在!");
		}
				
	}	
	
}

spring security配置文件

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled =true) // 启用授权注解
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {	
	
	/** 获取数据库中信息存到User对象中 */
	@Bean
    public UserDetailsService userService(){ //注册userService 的bean
        return new UserServiceImpl();
    }
	
	/**加密密码*/
	@Bean
	PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	/**MD5加密密码*/
	@Bean
	PasswordEncoder md5PasswordEncoder() {
		return new MD5PasswordEncoder();
	}
	
	/** 放行静态资源 */
	@Override
    public void configure(WebSecurity web) throws Exception {
        //解决静态资源被拦截的问题
        web.ignoring().antMatchers("/css/**");
        web.ignoring().antMatchers("/js/**");
        web.ignoring().antMatchers("/images/**");
        web.ignoring().antMatchers("/login/**");
        //解决服务注册url被拦截的问题
        web.ignoring().antMatchers("/resources/**");
    }
	
	@Override
    protected void configure(HttpSecurity http) throws Exception {
		// 登录
		http.formLogin().loginPage("/toLogin").loginProcessingUrl("/doLogin")
		    .defaultSuccessUrl("/index")
		    .failureUrl("/toLogin?error=true");  
		//解决非thymeleaf的form表单提交被拦截问题
		http.csrf().disable();
		
		http
			.authorizeRequests()
			.antMatchers("/toLogin")
			.permitAll()
            .anyRequest()
            .authenticated()				
        ;
					
        //session管理
        //session失效后跳转到登录页面  
        http.sessionManagement().invalidSessionUrl("/toLogin");

        //单用户登录,如果有一个登录了,同一个用户在其他地方登录将前一个剔除下线
        //http.sessionManagement().maximumSessions(1).expiredSessionStrategy(expiredSessionStrategy());
        
		//单用户登录,如果有一个登录了,同一个用户在其他地方不能登录
	    http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);
	    //退出删除cookie
	    http.logout()
	        .permitAll()
	    	.logoutUrl("/logout")  //执行注销的url
	    	.invalidateHttpSession(true) // 指定是否在注销时让httpSession无效
	    	.deleteCookies("JESSIONID")  // 清除cookie
	    	.logoutSuccessUrl("/toLogin"); // 注销成功后跳转的url
	    super.configure(http);
	
	    //解决中文乱码问题
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        filter.setForceEncoding(true);
        //http.addFilterBefore(filter,CsrfFilter.class);

        http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);
		
	}
	
	/**
	 * 认证器
	 */
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		// 自定义加密
		auth.userDetailsService(userService()).passwordEncoder(md5PasswordEncoder());		
	}

	
}

自定义的MD5加密类

这里的“123”对应UserService实现类中的123,模拟加密盐
MD5Utils是我的加密类

@Component
public class MD5PasswordEncoder implements PasswordEncoder {

	/**
	 * 加密
	 */
	@Override
	public String encode(CharSequence rawPassword) {
		
		return MD5Utils.encryptPassword(rawPassword.toString());
	}
	
	/**
	 * 密码匹配器
	 * rawPassword 用户前端输入的密码
	 * encodedPassword 数据库中待匹配的密码
	 */
	@Override
	public boolean matches(CharSequence rawPassword, String encodedPassword) {
		
		return encodedPassword.equals(MD5Utils.encryptPassword(rawPassword.toString()+"123"));
	}

}

controller层

@Controller
public class UserController {
    /**
     * ROLE_USER 是角色名称
     */
	@PreAuthorize("hasRole('ROLE_USER')")
	@RequestMapping("/update")
	@ResponseBody
	public String update() {
		System.out.println("这是修改请求");
		return "update";
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值