1.自定义Realm实现认证
(Realm,开发者自定义的模块,根据项目的需求,验证和授权的逻辑全部写在 Realm 中。)用户授权**只要进行登陆操作(controller里面的subject.login)就会执行doGetAuthenticationInfo方法
2.自定义Realm实现授权
1.用户授权
// 用户授权**只要进行登陆操作(controller里面的subject.login)就会执行doGetAuthenticationInfo方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User user = (User) principalCollection.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//获取用户的角色
List<Role> roleList = roleService.findRoleByUserId(user.getId());
Set<String> roleSet = new HashSet<>();
List<Integer> roleIds = new ArrayList<>();
for (Role role : roleList) {
roleSet.add(role.getRole());
roleIds.add(role.getId());
}
authorizationInfo.setRoles(roleSet);// 放入角色信息
List<String> permissionList = permissionService.findByRoleId(roleIds); // 放入权限信息
authorizationInfo.setStringPermissions(new HashSet<>(permissionList));
return authorizationInfo;
}
2.用户认证
// 用户认证
@Override
protected SimpleAuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authToken;
//从数据库里面取出来
User user = userService.findByAccount(token.getUsername());
if (user == null) {
return null;//抛出异常,用户名不存在
}
return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
}
3.定义拦截器,未登录的被拦截
@Configuration
public class ShiroConfig {
//被spring托管
//@Bean注解后便被spring托管,不加name属性,默认name值为方法名,这里就加一下吧
//创建realm对象,需要自定义类 (第一步:创建realm对象)
@Bean(name = "userRealm")
public UserRealm userRealm() {
return new UserRealm();
}
//DefaultWebSecurityManager (第二步:管理realm对象)
@Bean
public DefaultWebSecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联userRealm
securityManager.setRealm(userRealm());
return securityManager;
}
//ShiroFilterFactoryBean 路径过滤规则 (第三步:连接到前端)
@Bean
public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/");
Map<String, String> map = new LinkedHashMap<>();
/**
*添加shiro的内置过滤器
anon: 无需认证即可访问
authc: 必须认证才能用
user: 必须拥有 “记住我” 功能才能用
perms: 拥有对某个资源的权限才能用
role: 拥有某个角色权限才能访问
*/
// 有先后顺序
map.put("/login", "anon"); // 允许匿名访问(无需认证就可以访问)
//role需要某一个角色就可以访问
map.put("/**", "authc"); // 进行身份认证后才能访问
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
//若访问时用户未认证,则跳转至登录页面
// shiroFilterFactoryBean.setLoginUrl("/toLogin");
return shiroFilterFactoryBean;
}
/**
* 开启Shiro注解模式,可以在Controller中的方法上添加注解
*
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
@Qualifier("securityManager") DefaultSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
4.登录接口
@PostMapping("/login")
public ServerResponseVO login(@RequestParam(value = "account") String account,
@RequestParam(value = "password") String password, HttpSession httpSession, HttpServletRequest request) {
Subject userSubject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(account, password);
System.out.println("=========================="+request.getSession()+"======================"+request.getCookies());
try {
// 登录验证
userSubject.login(token);
return ServerResponseVO.success();//登录成功
} catch (UnknownAccountException e) {//用户名不存在
return ServerResponseVO.error(ServerResponseEnum.ACCOUNT_NOT_EXIST);
} catch (DisabledAccountException e) {//
return ServerResponseVO.error(ServerResponseEnum.ACCOUNT_IS_DISABLED);
} catch (IncorrectCredentialsException e) {//密码不存在
return ServerResponseVO.error(ServerResponseEnum.INCORRECT_CREDENTIALS);
} catch (Throwable e) {
e.printStackTrace();
return ServerResponseVO.error(ServerResponseEnum.ERROR);
}
}
5.项目源码,拉下来就可以跑:
链接:https://pan.baidu.com/s/10sj3pDvhmcX2iAslK1Xzpw
提取码:0km1
复制这段内容后打开百度网盘手机App,操作更方便哦