目录
2.创建Realm(名字任意)类 并extends AuthorizingRealm
一.
1.概述
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
2.三个核心组件:
Subject, SecurityManager 和 Realms
•Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)。
SecurityManager则管理所有用户的安全操作
Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。
二.整合 (连接后台数据库之后)
思路:shiro可以在登录的时候拦截请求,并让它返回指定页面,让它拦截未登录不能访问/user/update请求,并让其返回登录页面,所以要在控制器方法里获取用户输入的用户名和密码,shiro可以根据用户名和密码分别进行判断,在UserRealm里面根据获取的用户名查询数据库里的记录,可能有多个用户名相同的,所以返回的是集合,然后确定完用户名正确之后,根据获取的记录获得其用户名的所有密码,遍历进行判断。
1.导入shiro依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
2.创建Realm(名字任意)类 并extends AuthorizingRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权doGetAuthorizationInfo");
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了认证doGetAuthorizationInfo");
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
// 根据名字查用户 并查出其pwd
List<User> users = userService.findUsersByName(userToken.getUsername());
if (users.isEmpty()) {
//抛出异常:用户名不存在
return null;
}
// 数组集合直接放都出错 ,根据姓名查出的用户又不只是一个
// 密码认证shiro自己去做,防止密码泄露,经过了加密的;
// SimpleAuthenticationInfo(Object principal, Object credentials, String realmName)
int i = 0;
String[] pwd = new String[users.size()];
for (User u : users
) {
pwd[i] = u.getPwd();
if (new String(userToken.getPassword()).equals(pwd[i])) {
return new SimpleAuthenticationInfo("", pwd[i].toCharArray(), "");
}
}
return new SimpleAuthenticationInfo("", pwd[0], "");
}
}
3.交给spring管理其对象
@Configuration
public class MyShiroConfig {
@Bean(name="userRealm")
public UserRealm userRealm(){
// realm(领域)连接数据
return new UserRealm();
}
@Bean(name="securityManager")
public DefaultWebSecurityManager geDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
//绑定userRealm()
DefaultWebSecurityManager securityManager= new DefaultWebSecurityManager();
//关联 UserRealm
securityManager.setRealm(userRealm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean getShiroFileFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加shiro的内置过滤器
/*
* anon:无需认证就可以访问
* authc;必须认证才能访问
* perms:拥有对某个资源的权限
* */
//拦截 必须是链式
Map<String,String> map=new LinkedHashMap<String,String>();
// map.put("/user/add","anon");//所有人都可以访问
// map.put("/user/update","authc");//只有认证才可以访问
//授权,正常情况下,没有授权会跳转到未授权页面
// map.put("/user/add","perms[add]");//虽然认证了但是没有权限,
// role 拥有某个角色的权限才能访问
// user:add不能进入。要进入无权限页面,除非授权
// map.put("/user/update","perms[update]");
map.put("/user/update","authc");
bean.setFilterChainDefinitionMap(map);
bean.setLoginUrl("/user/toLogin");//没有权限回到login
//未授权的页面
// bean.setUnauthorizedUrl("/user/noauth");
return bean;
}
4.控制器方法
@RequestMapping("/login")
public String login(String username, String pwd, ModelMap map){
//获取当前用户
Subject su= SecurityUtils.getSubject();
//封装用户的登录数据
UsernamePasswordToken token=new UsernamePasswordToken(username,pwd);
//执行登录的方法
try{
su.login(token);
return "/update";
}catch(UnknownAccountException e){
map.put("msg","用户名错误");
return "login";
}catch(IncorrectCredentialsException e){
map.put("msg","密码错误");
return "login";
} //未授权的页面
// bean.setUnauthorizedUrl("/user/noauth");
// return bean;
}
@RequestMapping("/toLogin")
public String toLogin(){
return "login";
}