目录
1.Shiro自定义Realm实现认证和授权
2.认证
3.授权
4.ShiroConfiguration类
正文
1.Shiro自定义Realm实现认证和授权
我们在配置 Shiro 的用户信息和权限数据的时候,都是从 shiro.ini 配置文件里面读取的,这些数据能不能从我们本地的数据库中进行读取呢? 当然可以, 可以通过 JdbcRealm 进行读取,但是通过 JdbcRealm进行读取时,数据库的表的名称,表的字段都必须固定,非常不利于扩展。所以,我们需要自定义Realm.自定义Realm 时,我们常常 使用org.apache.shiro.realm.AuthorizingRealm 类。让我们自定义的类, 继承 AuthorizingRealm 抽象类
public abstract class AuthorizingRealm
extends AuthenticatingRealm
implements Authorizer, Initializable, PermissionResolverAware, RolePermissionResolverAware{
...
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection);
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken paramAuthenticationToken)
...
}
AuthorizingRealm 有两个抽象方法, doGetAuthorizationInfo 和 doGetAuthenticationInfo其中, doGetAuthorizationInfo 进行授权操作, doGetAuthenticationInfo 进行认证操作。认证操作时,常常返回 AuthenticationInfo的子类 SimpleAuthenticationInfo授权操作时, 常常返回 AuthorizationInfo的子类 simpleAuthorizationInfo关于Shiro 自定义 Realm获取数据的使用方式,我们详细了解一下。
2.认证
在登录时根据用户身份进行认证
try{
UsernamePasswordToken token=new UsernamePasswordToken(username,password);
Subject subject= SecurityUtils.getSubject();
subject.login(token);
User user=(User)subject.getPrincipal();
session.setAttribute("user",user);
return ("admin/index");
}catch(Exception e){
redirectAttributes.addFlashAttribute("message","用户名或密码错误");
return "redirect:/admin";
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token=(UsernamePasswordToken) authenticationToken;
String username=token.getUsername();
String password=new String(token.getPassword());
User user=userService.checkUser(username,password);
if(user!=null){
return new SimpleAuthenticationInfo(user,password,this.getName());
}
return null;
}
3.授权
根据用户身份分别授予不同权限
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
User user=(User) principalCollection.getPrimaryPrincipal();
Set<Role> roles=user.getRoles();
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
for(Role role:roles){
info.addRole(role.getName());
for(Permission p:role.getPermissions()){
info.addStringPermission(p.getCode());
}
}
return info;
}
删除时权限
@RequiresPermissions(value="user-delete")
编辑和新增时的权限
@RequiresRoles(value="admin")
4.ShiroConfiguration类
package com.zr;
import com.zr.reaml.NewsRealm;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfiguration {
@Bean
public NewsRealm getRealm(){
return new NewsRealm();
}
@Bean
public SecurityManager securityManager(NewsRealm realm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/admin");
shiroFilterFactoryBean.setUnauthorizedUrl("/admin/unauthor");
Map<String,String> filterMap=new LinkedHashMap<>();
//anon authc
filterMap.put("/admin/login","anon");
filterMap.put("/admin/**","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}