浏览器和postman中都会提示登录成功,但浏览器还会重定向到登陆页;postman登录后访问主页是没问题的。今天尝试部署前,在idea上这一块一直很正常的,部署后不知道什么原因。谢谢大神,相关代码贴如下
shiro.ini配置
[main]
# cacheManager,请确保 ehcache的声明在其他所有realm声明之前
#-------EhCache------#
cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager
cacheManager.cacheManagerConfigFile = classpath:ehcache.xml
#-------Session管理器------# 关闭定时校验机制,持久化环境下会非常耗内存
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionManager.sessionValidationSchedulerEnabled = false
#-------带缓存的SessionDAO------#
sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
sessionDAO.cacheManager = $cacheManager
sessionDAO.activeSessionsCacheName = shiro-activeSessionCache
#-------sessionManager创建会话Cookie的模板------#
######1.name:设置Cookie名字,默认为JSESSIONID;
######2.domain:设置Cookie的域名,默认空,即当前访问的域名;
######3.path:设置Cookie的路径,默认空,即存储在域名根下;
######4.maxAge:设置Cookie的过期时间,秒为单位,默认-1表示关闭浏览器时过期Cookie;
######5.httpOnly:通过程序(JS脚本、Applet等)将无法读取到Cookie信息,这样能有效的防止XSS攻击。
######6.sessionIdCookie:是否启用/禁用Session Id Cookie,默认是启用的;如果禁用后将不会设置Session Id Cookie,即默认使用了Servlet容器的JSESSIONID,且通过URL重写(URL中的“;JSESSIONID=id”部分)保存Session Id。
sessionIdCookie = org.apache.shiro.web.servlet.SimpleCookie
sessionIdCookie.name = sid
#sessionIdCookie.domain=wizzer.cn
#sessionIdCookie.path=
sessionIdCookie.maxAge = 946080000
sessionIdCookie.httpOnly = true
sessionManager.sessionIdCookie = $sessionIdCookie
sessionManager.sessionIdCookieEnabled = true
sessionManager.globalSessionTimeout = 3600000
sessionManager.sessionDAO = $sessionDAO
rememberMeCookie = org.apache.shiro.web.servlet.SimpleCookie
rememberMeCookie.name = remember
rememberMeCookie.maxAge = 604800
rememberMeCookie.httpOnly = true
rememberMeManager = cn.wizzer.framework.shiro.remember.LightCookieRememberMeManager
rememberMeManager.cookie = $rememberMeCookie
#-------CredentialsMatcher密码验证器------#
######1.storedCredentialsHexEncoded:是否存储散列后的密码为16进制,需要和生成密码时的一样,默认是base64
######2.hashIterations:密码迭代次数
sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
sha256Matcher.storedCredentialsHexEncoded = false
sha256Matcher.hashIterations = 1024
sha256Matcher.hashSalted = true
#-------Realm------#
shiroDbRealm = com.yolk.app.web.commons.shiro.realm.SimpleAuthorizingRealm
shiroDbRealm.credentialsMatcher = $sha256Matcher
authcStrategy = cn.wizzer.framework.shiro.pam.AnySuccessfulStrategy
securityManager.realms = $shiroDbRealm
securityManager.authenticator.authenticationStrategy = $authcStrategy
securityManager.sessionManager = $sessionManager
securityManager.cacheManager = $cacheManager
securityManager.rememberMeManager = $rememberMeManager
#-------authc拦截器------#表示需要身份认证通过后才能访问
###### authc的默认实现就是FormAuthenticationFilter(可以不用配置),有两个功能,1.访问指定路径时,如果用户未登录,跳转到loginUrl;2.符合预设格式的表单提交到loginUrl时,将有authc拦截器提取请求参数并执行验证
###### usernameParam=username和passwordParam=password均是表单的默认name,可更改
authc = com.yolk.app.web.commons.shiro.filter.SimpleAuthenticationFilter
authc.loginUrl = /yolk/user/
authc.successUrl = /yolk/zdd/
authc.usernameParam=username
authc.passwordParam=password
###1、URL目录是基于HttpServletRequest.getContextPath()此目录设置
###2、URL可使用通配符,**代表任意子目录
###3、Shiro验证URL时,URL匹配成功便不再继续匹配查找。所以要注意配置文件中的URL顺序,尤其在使用通配符时。
[urls]
/yolk/user/ = anon
/yolk/user/login = anon
/yolk/** = authc
/assets/** = anon
/** = anon
login.html
success: function (data, status, xhr) {
alert(data.msg);
if (data.code == 0) {
window.location.href = "${base!}/yolk/zdd";
}
}
UserControl.java
/**
* 登入界面
*
* @return
*/
@At("")
@Ok("re")/*根据返回值决定视图,视图的实现类为:org.nutz.mvc.view.ViewZone*/
@Filters
public Object index(HttpServletRequest req, HttpSession session) {
Subject subject = SecurityUtils.getSubject();
if (subject.isAuthenticated()) {
//已登陆状态
return "redirect:/yolk/zdd/";
}
try {
//生成一组公钥和私钥,他們共用一组模数,但指数不同
HashMap<String, Object> map = RSAUtil.getKeys();
RSAPublicKey publicKey = (RSAPublicKey) map.get("public");
RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");
//公有模数
String publicKeyModulus = publicKey.getModulus().toString(16);
//公钥指数
String publicKeyExponent = publicKey.getPublicExponent().toString(16);
//前端利用模数和公钥指数进行加密
req.setAttribute("publicKeyExponent", publicKeyExponent);
req.setAttribute("publicKeyModulus", publicKeyModulus);
//保存私钥,用于解密
session.setAttribute("platformPrivateKey", privateKey);
} catch (Exception e) {
e.printStackTrace();
}
return "beetl:/user/login.html";
}
SimpleAuthenticationFilter.java
/**
* 根据请求参数中的用户名、密码、rememberMe生成Token
*
* @param request
* @return
*/
protected AuthenticationToken createToken(HttpServletRequest request ) {
String username = getUsername(request);
String password = getPassword(request);
boolean rememberMe = isRememberMe(request);
String host = getHost(request);
try {
RSAPrivateKey platformPrivateKey = (RSAPrivateKey) request.getSession().getAttribute("platformPrivateKey");
log1.debug(String.format("username:%s password:%s platformPrivateKey:%s", username, password, platformPrivateKey));
if (platformPrivateKey != null) {
password = RSAUtil.decryptByPrivateKey(password, platformPrivateKey);
}
} catch (Exception e) {
e.printStackTrace();
}
return new UsernamePasswordToken(username, password, rememberMe, host);
}
SimpleAuthenticationFilter#createToken中platformPrivateKey也莫名奇妙的为null了