Authentication
:认证、验证Authorization
:授权Session Management
:会话管理Crytography
:加密机制Subject
SecurityManager
总结:
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Quickstart {
private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
public static void main(String[] args) {
// 工厂模式,通过shiro.ini 配置文件中的信息,生成一个工厂实例
Factory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
// 通过SecurityUtils 获取当前执行的用户Subject:
Subject currentUser = SecurityUtils.getSubject();
//通过当前用户拿到Shiro的Session 可以脱离web存值取值
Session session = currentUser.getSession();
// 使用session存值取值
session.setAttribute("someKey", "aValue");
String value = (String) session.getAttribute("someKey");
if (value.equals("aValue")) {
log.info("Retrieved the correct value! [" + value + "]");
}
// 让我们登录当前用户,以便我们可以检查角色和权限:
// 这里和SpringSecurity 使用了类似的代码,判断用户是否被认证
if (!currentUser.isAuthenticated()) {
//如果被认证,就可以获得一个令牌(token )
//通过用户的账号密码生成一个令牌
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
//设置记住我功能
token.setRememberMe(true);
try {
//执行登录操作
currentUser.login(token);
} catch (UnknownAccountException uae) {
//如果用户名不存在
log.info("There is no user with username of " + token.getPrincipal());
} catch (IncorrectCredentialsException ice) {
// 如果密码不正确
log.info("Password for account " + token.getPrincipal() + " was incorrect!");
} catch (LockedAccountException lae) {
//用户被锁定,如密码输出过多,则被锁住
log.info("The account for username " + token.getPrincipal() + " is locked. " +"Please contact your administrator to unlock it.");
}
// ... 在此处捕获更多异常
catch (AuthenticationException ae) {
//意外情况?错误?
}
}
//currentUser些用法
//打印其标识主体(在这种情况下,为用户名) :
log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
// 检查角色是否存在
if (currentUser.hasRole("schwartz")) {
log.info("May the Schwartz be with you!");
} else {
log.info("Hello, mere mortal.");
}
//粗粒度
if (currentUser.isPermitted("lightsaber:wield")) {
log.info("You may use a lightsaber ring. Use it wisely.");
} else {
log.info("Sorry, lightsaber rings are for schwartz masters only.");
}
//细粒度
if (currentUser.isPermitted("winnebago:drive:eagle5")) {
log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'." +"Here are the keys - have fun!");
} else {
log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
}
//注销
currentUser.logout();
//结束
System.exit(0);
}
}
主要流程:
//获取当前对象
Subject currentUser = SecurityUtils.getSubject();
//根据当前对象获取对应的Session
Session session = currentUser.getSession();
//判断用户是否被认证,根据用户名和密码生成令牌
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
//设置记住我功能
token.setRememberMe(true);
//拿到令牌进行登录
currentUser.login(token);
//打印其标识主体
currentUser.getPrincipal()
//注销
currentUser.logout();
package com.mtf.config;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class Realm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权方法!");
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了认证方法!");
return null;
}
}
AuthorizingRealm
重写里面的“认证”和“授权”方法package com.mtf.config;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ShiroConfig {
@Bean(name = "shiroFilterFactoryBean")
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
return shiroFilterFactoryBean;
}
@Bean(name = "defaultWebSecurityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRemal") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm);
return securityManager;
}
@Bean(name = "userRealm")
public UserRealm getUserRealm(){
return new UserRealm();
}
}
请求拦截
//在配置类中添加shiro内置过滤器
//添加shiro内置过滤器
Map filterMap = new LinkedHashMap<>();
/*
anon : 无需认证,就可以访问
authc : 必须认证,才能访问
user : 必须拥有 “记住我”功能才能用
perms : 拥有对某个资源的权限才能访问
role : 拥有某个角色权限才能访问
*/
filterMap.put("/functions/*","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
//设置拦截后要跳转的页面,一般是登录页面
shiroFilterFactoryBean.setLoginUrl("/toLogin");
用户认证(与数据库交互判断登录的用户名账号密码是否正确)
//Controller
//用户认证
@RequestMapping("/login")
public String Login(String username, String password, Model model){
//获取当前对象
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
token.setRememberMe(true);
try {
if (!subject.isAuthenticated()){
subject.login(token);
return "index";
}
} catch (UnknownAccountException e) {
model.addAttribute("msg","用户名错误!");
return "login";
}catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误!");
return "login";
}
return "index";
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了认证方法!");
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
User user = userService.queryByName(token.getUsername());
if (user==null){
return null;
}
return new SimpleAuthenticationInfo("",user.getPassword(),"");
}
用户授权
//权限设置
filterMap.put("/functions/*","perms[functions:*]");
//通过关键字段来判断用户权限
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权方法!");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
Subject subject = SecurityUtils.getSubject();
User user = (User) subject.getPrincipal();
info.addStringPermission(user.getPerms());
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("执行了认证方法!");
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
User user = userService.queryByName(token.getUsername());
if (user==null){
return null;
}
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
shiro和thymeleaf整合
// 整合ShiroDialect:用来整合shiro-thymeleaf
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}