一、shiro認(rèn)證
1、請(qǐng)求認(rèn)證
Subject subject = SecurityUtils.getSubject();// 根據(jù)運(yùn)行環(huán)境返回subject
subject.login(token);// 這里的token一般指的是 UsernamePasswordToken玷禽,參數(shù)有
// String username, String password, boolean rememberMe, String host 膘流,有多種構(gòu)造函數(shù)
2早龟、通過SecurityManager執(zhí)行認(rèn)證
public void login(AuthenticationToken token) throws AuthenticationException {
this.clearRunAsIdentitiesInternal();
Subject subject = this.securityManager.login(this, token);// 調(diào)用securityManager
String host = null;
PrincipalCollection principals;
if (subject instanceof DelegatingSubject) {
DelegatingSubject delegating = (DelegatingSubject)subject;
principals = delegating.principals;
host = delegating.host;
} else {
principals = subject.getPrincipals();
}// 無論怎么樣principals = subject.getPrincipals();既用戶名
if (principals != null && !principals.isEmpty()) {
this.principals = principals;
this.authenticated = true;
if (token instanceof HostAuthenticationToken) {
host = ((HostAuthenticationToken)token).getHost();
}
if (host != null) {
this.host = host;
}
Session session = subject.getSession(false);
if (session != null) {
this.session = this.decorate(session);
} else {
this.session = null;
}
} else {
String msg = "Principals returned from securityManager.login( token ) returned a null or empty value. This value must be non null and populated with one or more elements.";
throw new IllegalStateException(msg);
}
}
3、SecurityManager通過ModularRealmAuthenticator再通過realm進(jìn)行認(rèn)證
在自定義的Realm中完成認(rèn)證
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//獲取用戶的輸入的賬號(hào).
String username = (String) token.getPrincipal();
User user = userService.selectByUsername(username);
String password = user.getPassword();
if (user == null) throw new UnknownAccountException();
if (0 == user.getEnable()) {
throw new LockedAccountException(); // 帳號(hào)鎖定
}
//通過這個(gè)進(jìn)行認(rèn)證,并返回
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, null, getName());
Session session = SecurityUtils.getSubject().getSession();// 當(dāng)驗(yàn)證都通過后,把用戶信息放在session里
session.setAttribute("userSession", user);
session.setAttribute("userSessionId", user.getId());
return simpleAuthenticationInfo;
}
4、認(rèn)證的配置
這些配置在shiro的配置文件中完成
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());// 憑證驗(yàn)證器
return myShiroRealm;
}
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {// 憑證驗(yàn)證器
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:這里使用MD5算法;
hashedCredentialsMatcher.setHashIterations(1);//散列的次數(shù)炎辨,比如散列兩次,相當(dāng)于 md5(md5(""));
return hashedCredentialsMatcher;
}
二聪姿、shiro授權(quán)
1碴萧、ModularRealmAuthenticator通過realm進(jìn)行認(rèn)證
在自定義的Realm中完成授權(quán),將用戶的權(quán)限查出末购,配置到info中去勿决。
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String username = (String) principalCollection.getPrimaryPrincipal();
User user = userService.selectByUsername(username);
Map<String, Object> map = new HashMap();
map.put("userid", user.getId());
List<Resources> resourcesList = resourcesService.loadUserResources(map);
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // 權(quán)限信息對(duì)象info
for (Resources resources : resourcesList) {
info.addStringPermission(resources.getResurl()); // 在這里存放查出的用戶的所有的角色(role)及權(quán)限(permission)
}
return info;
}
2、授權(quán)的配置招盲,通過filterChainDefinitionMap在Shiro的攔截器中配置
這些配置在shiro的配置文件中完成
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setSuccessUrl("/usersPage");// 登錄成功跳轉(zhuǎn)的頁
shiroFilterFactoryBean.setUnauthorizedUrl("/403");// 未授權(quán)界面;
Map<String, String> filterChainDefinitionMap = new LinkedHashMap();
filterChainDefinitionMap.put("/logout", "logout");// 配置登出地址低缩,不需要專門去寫控制器
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/font-awesome/**", "anon");// 首先放過一般的靜態(tài)資源
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); // 配置所有需要攔截的地址
return shiroFilterFactoryBean;
}
2.1配置規(guī)則
// 將需要配置的地址放入map中,規(guī)則如下:
/**
anon:例子/admins/**=anon 沒有參數(shù),表示可以匿名使用咆繁。
authc:例如/admins/user/**=authc表示需要認(rèn)證(登錄)才能使用讳推,沒有參數(shù)
roles(角色):例子/admins/user/**=roles[admin],參數(shù)可以寫多個(gè),多個(gè)時(shí)必須加上引號(hào)玩般,
并且參數(shù)之間用逗號(hào)分割银觅,當(dāng)有多個(gè)參數(shù)時(shí),例如admins/user/**=roles["admin,guest"]坏为,
每個(gè)參數(shù)通過才算通過究驴,相當(dāng)于hasAllRoles()方法。
perms(權(quán)限):例子/admins/user/**=perms[user:add:*]匀伏,參數(shù)可以寫多個(gè)洒忧,多個(gè)時(shí)必須加上引號(hào)够颠,
并且參數(shù)之間用逗號(hào)分割熙侍,例如/admins/user/**=perms["user:add:*,user:modify:*"],
當(dāng)有多個(gè)參數(shù)時(shí)必須每個(gè)參數(shù)都通過才通過履磨,想當(dāng)于isPermitedAll()方法蛉抓。
rest:例子/admins/user/**=rest[user],根據(jù)請(qǐng)求的方法,相當(dāng)于/admins/user/**=perms[user:method] 剃诅,
其中method為post巷送,get,delete等矛辕。
port:例子/admins/user/**=port[8081],當(dāng)請(qǐng)求的url的端口不是8081是跳轉(zhuǎn)到
schemal://serverName:8081?queryString,其中schmal是協(xié)議http或https等惩系,
serverName是你訪問的host,8081是url配置里port的端口,queryString是你訪問的url里的如筛?后面的參數(shù)。
authcBasic:例如/admins/user/**=authcBasic沒有參數(shù)表示httpBasic認(rèn)證
ssl:例子/admins/user/**=ssl沒有參數(shù)抒抬,表示安全的url請(qǐng)求杨刨,協(xié)議為https
user:例如/admins/user/**=user沒有參數(shù)表示必須存在用戶,當(dāng)?shù)侨氩僮鲿r(shí)不做檢查
*/
// 詳情參考shiro.web.filter源碼
三擦剑、shiro認(rèn)證
在shiro的配置文件中加入
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
html中加入xmlns
<html lang="zh_CN" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
maven依賴
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>1.2.1</version>
</dependency>