shiro的了解 (2014-11-06 15:13:14)
标签: 股票 分类: java
shiro学习:
大体功能是认证、授权、加密、会话管理
一、SecurityManager
所有基于web的应用程序都是用 DefaultWebSecurityManager进行管理,它主要提供如下方面的功能
Authentication(认证)
1、web应用FormAuthenticationFilter拦截器
在web应用中认证是通过FormAuthenticationFilter拦截器来实现的
分析对应源代码:
整个拦截器的执行方法是在AdviceFilter.doFilterInternal进行封装
它调用下面三个方法:
boolean continueChain = preHandle(request, response); //是否继续执行后续拦截器链操作
if (continueChain) {
executeChain(request, response, chain);//继续执行拦截器后面的操作
}
postHandle(request, response);//拦截器执行完后的操作
preHandle调用
onPreHandle(request, response, pathConfig)
{
return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response, mappedValue);
}
isAccessAllowed(request, response, mappedValue)//是否允许访问
在AuthenticatingFilter.isAccessAllowed中进行了如下实现:
Subject subject = getSubject(request, response);
return subject.isAuthenticated() || (!isLoginRequest(request, response) && isPermissive(mappedValue));
//只要当前用户已经过认证就直接返回true,
如果isAccessAllowed返回false,则系统执行onAccessDenied
FormAuthenticationFilter.onAccessDenied实现对应的方法
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
if (isLoginRequest(request, response)) //判断请求是否是登录请求
{
if (isLoginSubmission(request, response)) //判断请求是否是post方法
{
if (log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
}
return executeLogin(request, response);//执行登录验证
} else //如果是get方法则会返回true,跳转到登陆页面
{
if (log.isTraceEnabled()) {
log.trace("Login page view.");
}
//allow them to see the login page ;)
return true;
}
}
//如果访问的是非登录页面,则跳转到登录页面
else {
if (log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the " +
"Authentication url [" + getLoginUrl() + "]");
}
saveRequestAndRedirectToLogin(request, response);
return false;
}
}
//executeLogin执行真正的登录操作
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
AuthenticationToken token = createToken(request, response); //创建用户的身份、凭证
if (token == null) {
String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +
"must be created in order to execute a login attempt.";
throw new IllegalStateException(msg);
}
try {
Subject subject = getSubject(request, response);
subject.login(token); //执行shiro的登录操作
return onLoginSuccess(token, subject, request, response);//登录成功
} catch (AuthenticationException e) {
return onLoginFailure(token, e, request, response);//登录失败
}
}
在FormAuthenticationFilter中登录成功和登录失败的具体实现
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
ServletRequest request, ServletResponse response) throws Exception {
issueSuccessRedirect(request, response); //直接重定向到成功页面
//we handled the success redirect directly, prevent the chain from continuing:
return false; //不再执行过滤器链后面的操作
}
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
ServletRequest request, ServletResponse response) {
setFailureAttribute(request, e); //登录失败,设置异常信息继续执行过滤器链后面的操作
//login failed, let request continue back to the login page:
return true;
}
SessionManager(session管理)
DefaultWebSecurityManager-->sessionManager
有下面几种具体的实现
1、ServletContainerSessionManager(默认)
ServletContainerSessionManager使用web容器提供的session进行管理,所以默认使用DefaultWebSecurityManager管理session和直接使用web容器的session
是没有区别的
ServletContainerSessionManager管理的session对象是org.apache.shiro.web.session.HttpServletSession,该对象代理封装了对javax.servlet.http.HttpSession的操作
2、DefaultWebSessionManager
该session管理器默认指定的sessionDAO = new MemorySessionDAO();
它是基于当前内存来进行管理session,没有使用web容器的session;该中方式在集群环境时会出现问题,比如在同一session中访问不同的机器,则可能某些机器存在session值,有些不存在
除非web server配置成ip_hosts
可以通过该sessionManager来实现通过分布式缓存进行多台机器的session共享,可以采用如下配置
CacheManage(缓存管理)
Realm中使用缓存
在Realm中有2个使用缓存的地方
1、认证缓存
首先判断getAuthenticationCache()是否为空,如果未设置则判断authenticationCachingEnabled=true&&cachingEnabled=true如果都为true
则通过设置的cacheManager中取出name=authenticationCacheName的缓存
也就是说要想使用认证缓存,则在Realm中有2种方式设置
一种是通过设置cacheManager
然后设置 authenticationCacheName(认证缓存名)authenticationCachingEnabled=true、cachingEnabled=true
或者直接设置
public void setAuthenticationCache(Cache authenticationCache)
2、授权缓存
首先判断getAuthorizationCache()如果未设置则判断authorizationCachingEnabled=true&&cachingEnabled=true如果都为true
则通过设置的cacheManager中取出name=authorizationCacheName的缓存
也就是说要想使用授权缓存,则在Realm中有2种方式设置
一种是通过设置cacheManager
然后设置 authorizationCacheName(授权缓存名)、authorizationCachingEnabled=true、cachingEnabled=true
或者直接设置
public void setAuthorizationCache(Cache authorizationCache)
上面有很多变量值需要设置,Realm默认情况下
authorizationCachingEnabled=true(是否可授权缓存)
authenticationCachingEnabled=false(是否可认证缓存)
cachingEnabled=true(是否可缓存)
目前认证缓存功能使用不了,当缓存时序列化时对应的对象无法序列化;而且一般也不要使用认证缓存,避免修改密码无法及时生效
授权缓存可以在session期间有效,session过期后重新取授权
SessionManager中使用缓存
在这里使用缓存的目的主要是管理系统session的缓存,比如系统如果想使用memcached来管理session就可以在这里配置
标签: 股票 分类: java
shiro学习:
大体功能是认证、授权、加密、会话管理
一、SecurityManager
所有基于web的应用程序都是用 DefaultWebSecurityManager进行管理,它主要提供如下方面的功能
Authentication(认证)
1、web应用FormAuthenticationFilter拦截器
在web应用中认证是通过FormAuthenticationFilter拦截器来实现的
分析对应源代码:
整个拦截器的执行方法是在AdviceFilter.doFilterInternal进行封装
它调用下面三个方法:
boolean continueChain = preHandle(request, response); //是否继续执行后续拦截器链操作
if (continueChain) {
executeChain(request, response, chain);//继续执行拦截器后面的操作
}
postHandle(request, response);//拦截器执行完后的操作
preHandle调用
onPreHandle(request, response, pathConfig)
{
return isAccessAllowed(request, response, mappedValue) || onAccessDenied(request, response, mappedValue);
}
isAccessAllowed(request, response, mappedValue)//是否允许访问
在AuthenticatingFilter.isAccessAllowed中进行了如下实现:
Subject subject = getSubject(request, response);
return subject.isAuthenticated() || (!isLoginRequest(request, response) && isPermissive(mappedValue));
//只要当前用户已经过认证就直接返回true,
如果isAccessAllowed返回false,则系统执行onAccessDenied
FormAuthenticationFilter.onAccessDenied实现对应的方法
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
if (isLoginRequest(request, response)) //判断请求是否是登录请求
{
if (isLoginSubmission(request, response)) //判断请求是否是post方法
{
if (log.isTraceEnabled()) {
log.trace("Login submission detected. Attempting to execute login.");
}
return executeLogin(request, response);//执行登录验证
} else //如果是get方法则会返回true,跳转到登陆页面
{
if (log.isTraceEnabled()) {
log.trace("Login page view.");
}
//allow them to see the login page ;)
return true;
}
}
//如果访问的是非登录页面,则跳转到登录页面
else {
if (log.isTraceEnabled()) {
log.trace("Attempting to access a path which requires authentication. Forwarding to the " +
"Authentication url [" + getLoginUrl() + "]");
}
saveRequestAndRedirectToLogin(request, response);
return false;
}
}
//executeLogin执行真正的登录操作
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
AuthenticationToken token = createToken(request, response); //创建用户的身份、凭证
if (token == null) {
String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +
"must be created in order to execute a login attempt.";
throw new IllegalStateException(msg);
}
try {
Subject subject = getSubject(request, response);
subject.login(token); //执行shiro的登录操作
return onLoginSuccess(token, subject, request, response);//登录成功
} catch (AuthenticationException e) {
return onLoginFailure(token, e, request, response);//登录失败
}
}
在FormAuthenticationFilter中登录成功和登录失败的具体实现
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
ServletRequest request, ServletResponse response) throws Exception {
issueSuccessRedirect(request, response); //直接重定向到成功页面
//we handled the success redirect directly, prevent the chain from continuing:
return false; //不再执行过滤器链后面的操作
}
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
ServletRequest request, ServletResponse response) {
setFailureAttribute(request, e); //登录失败,设置异常信息继续执行过滤器链后面的操作
//login failed, let request continue back to the login page:
return true;
}
SessionManager(session管理)
DefaultWebSecurityManager-->sessionManager
有下面几种具体的实现
1、ServletContainerSessionManager(默认)
ServletContainerSessionManager使用web容器提供的session进行管理,所以默认使用DefaultWebSecurityManager管理session和直接使用web容器的session
是没有区别的
ServletContainerSessionManager管理的session对象是org.apache.shiro.web.session.HttpServletSession,该对象代理封装了对javax.servlet.http.HttpSession的操作
2、DefaultWebSessionManager
该session管理器默认指定的sessionDAO = new MemorySessionDAO();
它是基于当前内存来进行管理session,没有使用web容器的session;该中方式在集群环境时会出现问题,比如在同一session中访问不同的机器,则可能某些机器存在session值,有些不存在
除非web server配置成ip_hosts
可以通过该sessionManager来实现通过分布式缓存进行多台机器的session共享,可以采用如下配置
CacheManage(缓存管理)
Realm中使用缓存
在Realm中有2个使用缓存的地方
1、认证缓存
首先判断getAuthenticationCache()是否为空,如果未设置则判断authenticationCachingEnabled=true&&cachingEnabled=true如果都为true
则通过设置的cacheManager中取出name=authenticationCacheName的缓存
也就是说要想使用认证缓存,则在Realm中有2种方式设置
一种是通过设置cacheManager
然后设置 authenticationCacheName(认证缓存名)authenticationCachingEnabled=true、cachingEnabled=true
或者直接设置
public void setAuthenticationCache(Cache authenticationCache)
2、授权缓存
首先判断getAuthorizationCache()如果未设置则判断authorizationCachingEnabled=true&&cachingEnabled=true如果都为true
则通过设置的cacheManager中取出name=authorizationCacheName的缓存
也就是说要想使用授权缓存,则在Realm中有2种方式设置
一种是通过设置cacheManager
然后设置 authorizationCacheName(授权缓存名)、authorizationCachingEnabled=true、cachingEnabled=true
或者直接设置
public void setAuthorizationCache(Cache authorizationCache)
上面有很多变量值需要设置,Realm默认情况下
authorizationCachingEnabled=true(是否可授权缓存)
authenticationCachingEnabled=false(是否可认证缓存)
cachingEnabled=true(是否可缓存)
目前认证缓存功能使用不了,当缓存时序列化时对应的对象无法序列化;而且一般也不要使用认证缓存,避免修改密码无法及时生效
授权缓存可以在session期间有效,session过期后重新取授权
SessionManager中使用缓存
在这里使用缓存的目的主要是管理系统session的缓存,比如系统如果想使用memcached来管理session就可以在这里配置