1.添加依赖包:
<!-- 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>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
2.添加shiro.ini配置(放在src目录下,mavan环境放置在src/main/resource目录下)
[main]
#realm
#自定义Realm
myRealm = com.jsaas.core.security.ShiroDbRealm
securityManager.realm = $myRealm
#配置shiro的密码验证方式为盐加密 也可以通过ShiroDbRealm 中 setCredentialsMatcher方法指定自定义的密码验证方式
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
credentialsMatcher.hashAlgorithmName=SHA-1
credentialsMatcher.hashIterations=1024
credentialsMatcher.storedCredentialsHexEncoded=true
myRealm.credentialsMatcher=$credentialsMatcher
#没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”
shiro.loginUrl = /tologin
#登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,则在登录自动跳转到那个需要登录的页面。不跳转到此。
shiro.successUrl = /sys/user/successUrl
#没有权限默认跳转的页面。
shiro.unauthorizedUrl = /403
#cache
shiroCacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
shiroCacheManager.cacheManagerConfigFile = classpath:ehcache.xml
securityManager.cacheManager = $shiroCacheManager
#session
#sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionDAO = com.jsaas.core.security.OnlineSessionDao
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionDAO.activeSessionsCacheName = shiro-activeSessionCache
sessionManager.sessionDAO = $sessionDAO
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.globalSessionTimeout = 360000
[urls]
/login/** = anon
/user/** = anon
/** = authc
配置web.xml文件
<!-- 配置apache shiro监听 -->
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<!-- 配置apache shiro过滤器 -->
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
3.ShiroDbRealm类
package com.jsaas.core.security;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.SqlPara;
import com.jsaas.model.User;
import com.jsaas.utils.Encodes;
import com.jsaas.utils.MyUtils;
/**
* @Title: ShiroDbRealm.java
* @Package com.jsaas.core.security
* @Description: TODO(shiro)
* @author tuozq
* @date 2017年11月3日 下午4:37:20
* @version V1.0
*/
public class ShiroDbRealm extends AuthorizingRealm {
/*@Override
public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
// TODO Auto-generated method stub
//自定义密码验证类 集成SimpleCredentialsMatcher 实现doCredentialsMatch方法
super.setCredentialsMatcher(new MyCredentialsMatcher());
}*/
/**
* 登录认证
* 身份认证
* SecurityUtils.getSubject().login(token) 时调用此方法
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// TODO Auto-generated method stub
CaptchaUsernamePasswordToken authcToken = (CaptchaUsernamePasswordToken) token;
if (authcToken.getUsername()==null||StrKit.isBlank(authcToken.getUsername())) {
throw new AuthenticationException("用户名不可以为空");
}
String account = authcToken.getUsername();
SqlPara sqlPara = Db.getSqlPara("user.findUser", Kv.by("account", account));
User user = User.dao.findFirst(sqlPara);
if(MyUtils.isNotNull(user)){
byte[] salt = Encodes.decodeHex(user.getSalt());
//UserPrincipal为自定义用户身份信息,登录成功后可以通过SecurityUtils.getSubject().getPrincipal()获取身份信息
return new SimpleAuthenticationInfo(new UserPrincipal(user), user.getPassword(), ByteSource.Util.bytes(salt), getName());
}
return null;
}
/**
* 此方法调用 hasRole,hasPermission的时候才会进行回调.
*
* 权限信息.(授权):
* 1、如果用户正常退出,缓存自动清空;
* 2、如果用户非正常退出,缓存自动清空;
* 3、如果我们修改了用户的权限,而用户不退出系统,修改的权限无法立即生效。
* :Authorization 是授权访问控制,用于对用户进行的操作授权,证明该用户是否允许进行当前操作,如访问某个链接,某个资源文件等。
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
}
4.注册时用户的密码需要进行SHA-1盐加密
public User sha1Password(User user){
//随机数 + 用户账号作为salt值
String salt = new SecureRandomNumberGenerator().nextBytes().toHex() + user.getAccount();
// 对密码加盐进行1024次SHA1加密
String _password = new SimpleHash("SHA-1", user.getPassword(), salt, 1024).toHex();
user.setSalt(salt);
//通过盐值加密密码
user.setPassword(_password);
return user;
}