1.加入shiro依赖
org.apache.shiro
shiro-spring
1.4.0
2.编写自定义Realm
package com.immo.phamacybus.shiro;
import java.util.List;
import org.apache.shiro.SecurityUtils;
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.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import com.immo.common.utils.MD5Utils;
import com.immo.phamacybus.common.UserInfo;
import com.immo.phamacybus.kettle.entity.KUser;
import com.immo.phamacybus.kettle.service.KUserService;
/**
* shiro自定义realm
*
* @author Linhai.Tan 2018-3-27
*
*/
public class CustomRealm extends AuthorizingRealm {
@Autowired
private KUserService kUserService;
/**
* 这是授权的方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 这是授权的方法,创建简单授权信息对象
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
UserInfo userInfo = (UserInfo) SecurityUtils.getSubject().getPrincipal();
//认证的时候已经把权限集合存进去了
authorizationInfo.addStringPermissions(userInfo.getAuthoritys());
return authorizationInfo;
}
/**
* 这是认证的方法,相当于登入
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 需要保存的用户信息
UserInfo userInfo = new UserInfo();
// 登入的帐号
String userName = (String) token.getPrincipal();
// 根据帐号查询对应的用户信息
KUser user = new KUser();
user.setUAccount(userName);
user.setDelFlag(1);
List list = null;
list = kUserService.selectList(user);
// 判断帐号是否存在,不存在抛出异常,或者返回null
if (list == null || list.size() == 0) {
throw new UnknownAccountException();
}
// 手动判断是否密码正确,正确则表明成功登入,查询出对应的信息存入subject
user = list.get(0);
String password = new String((char[]) token.getCredentials());
String userPassword = user.getUPassword();
if (userPassword.equals(MD5Utils.getMD5Code(password))) {
userInfo = kUserService.getUserInfo(user);
}
return new SimpleAuthenticationInfo(userInfo, userPassword, "CustomRealm");
}
}
3.编写shiroConfig
package com.immo.phamacybus.config;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.immo.common.config.ServiceParam;
import com.immo.phamacybus.shiro.CustomRealm;
/**
* shiro配置类
* @author Linhai.Tan 2018-3-27
*
*/
@Configuration
public class ShiroConfig {
@Bean(name = "securityManager")
public SecurityManager securityManager(@Qualifier("authRealm") CustomRealm customRealm,
@Qualifier("cookieRememberMeManager") CookieRememberMeManager cookieRememberMeManager) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置realm.
securityManager.setRealm(customRealm);
// 设置rememberMe管理器
securityManager.setRememberMeManager(cookieRememberMeManager);
return securityManager;
}
/**
* realm
*
* @return
*/
@Bean(name = "authRealm")
public CustomRealm myAuthRealm(
@Qualifier("hashedCredentialsMatcher") HashedCredentialsMatcher matcher) {
CustomRealm customRealm = new CustomRealm();
// 设置密码凭证匹配器
customRealm.setCredentialsMatcher(matcher); // myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return customRealm;
}
/**
* cookie对象;
*
* @return
*/
@Bean
public SimpleCookie rememberMeCookie() {
// 这个参数是cookie的名称,对应前端的checkbox 的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("shiro");
//
simpleCookie.setMaxAge(259200);
return simpleCookie;
}
/**
* 记住我管理器 cookie管理对象;
*
* @return
*/
@Bean(name = "cookieRememberMeManager")
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
return cookieRememberMeManager;
}
/**
* 密码匹配凭证管理器
*
* @return
*/
@Bean(name = "hashedCredentialsMatcher")
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("MD5");// 散列算法:这里使用MD5算法;
//hashedCredentialsMatcher.setHashIterations(1024);// 散列的次数,比如散列两次,相当于
// md5(md5(""));
return hashedCredentialsMatcher;
}
/**
* 开启shiro aop注解支持. 使用代理方式;所以需要开启代码支持; Controller才能使用@RequiresPermissions
*
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(
@Qualifier("securityManager") SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
/**
* 会话管理器
* @return
*/
@Bean
public DefaultWebSessionManager getDefaultWebSessionManager(){
DefaultWebSessionManager manager=new DefaultWebSessionManager();
manager.setGlobalSessionTimeout(Long.valueOf(ServiceParam.SESSION_OUT_TIME.value()+"000"));
manager.setDeleteInvalidSessions(true);
manager.setSessionIdCookie(rememberMeCookie());
return manager;
}
/**
* 调用SecurityUtils.setSecurityManager(securityManager)
* @param securityManager
* @return
*/
@Bean
public MethodInvokingFactoryBean methodInvokingFactoryBean(SecurityManager securityManager){
MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean();
bean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
bean.setArguments(new Object[]{securityManager});
return bean;
}
/**
* 设置过滤规则
* @param securityManager
* @return
*/
@Bean("shiroFilter")
public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必须设置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 拦截器.
Map map = new LinkedHashMap();
//全部放行,我们使用MVC拦截器拦截
map.put("/**", "anon");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/");
// 登录成功后要跳转的链接
//shiroFilterFactoryBean.setSuccessUrl("/index");
// 未授权界面;
// shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
}
4.整合完成
调用认证方法:
SecurityUtils.getSubject().login(new UsernamePasswordToken(userName, password));
必须要此权限才能访问此方法:
@RequiresPermissions("权限名称")