具有Shiro的Java SSM框架:没有ID错误的会话

时间:2018-08-09 03:18:54

标签: session mybatis shiro

环境:

  1. 春天4.2.4。发布,
  2. springmvc,
  3. mybatis 1.2.4,
  4. 四郎1.4.0

这是我的shiro-config:

@Configuration
public class ShiroConfig {
@Autowired
IPermissionService permissionService;


@Bean(name = "shiroFilter")
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
    System.out.println("ShiroConfiguration.shirFilter()");
    ShiroFilterFactoryBean shiroFilterFactoryBean = new 
ShiroFilterFactoryBean();
    shiroFilterFactoryBean.setSecurityManager(securityManager);

    Map<String, Filter> filters = new HashMap`enter code here`<>(16);
    filters.put("permission", new PermissionFilter());
    shiroFilterFactoryBean.setFilters(filters);

    shiroFilterFactoryBean.setLoginUrl("/index.html");


    shiroFilterFactoryBean.setSuccessUrl("/index/index");

    shiroFilterFactoryBean.setUnauthorizedUrl("/html/login.jsp");


    Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>();

    filterChainDefinitionMap.put("/static/**", "anon");
    filterChainDefinitionMap.put("/proGuard/project/getAll", "anon");
    filterChainDefinitionMap.put("/proGuard/project/getAllPosts", "anon");
    filterChainDefinitionMap.put("/proGuard/user/login", "anon");
    filterChainDefinitionMap.put("/proGuard/user/logout", "logout");   
    List<Permission> permissions = permissionService.getAllPermission();
    for (Permission permission : permissions) {
        filterChainDefinitionMap.put(permission.getPermissionUrl(), "permission[" + permission.getPermissionUrl() + "]");
    }
    filterChainDefinitionMap.put("/proGuard/**", "authc");
    shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    return shiroFilterFactoryBean;
}


@Bean
public SecurityManager  securityManager() {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(shiroRealm());
    securityManager.setSessionManager(sessionManager());
    return securityManager;
}


@Bean
public LoginRealm shiroRealm() {
    LoginRealm shiroRealm = new LoginRealm();
    shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
    return shiroRealm;
}


@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
    HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    hashedCredentialsMatcher.setHashAlgorithmName("md5");
    hashedCredentialsMatcher.setHashIterations(1024);
    return hashedCredentialsMatcher;
}

@Bean
public DefaultWebSessionManager sessionManager() {
    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
    // to solve session name "JSESSIONID"collision with tomcat container
    SimpleCookie shirocookie = new SimpleCookie("SHIROCOOKIE");
    sessionManager.setSessionIdCookie(shirocookie);
    System.err.println("ytj session: " + 
    sessionManager.getSessionIdCookie().getValue());

    return sessionManager;
}

}

这是我自定义的过滤器

public class PermissionFilter extends AccessControlFilter {
/**
 * logger
 */
private static final Logger LOGGER = 
LoggerFactory.getLogger(PermissionFilter.class);

@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {


    Subject subject = getSubject(request, response);

    String basePath =  ((HttpServletRequest) request).getContextPath();
    if (null != mappedValue) {
        String[] value = (String[]) mappedValue;
        for (String uri : value) {
            if (!StringUtils.isEmpty(basePath) && null != uri && uri.startsWith(basePath)) {
                uri = uri.replaceFirst(basePath, "");
            }
            SysUser user = (SysUser) subject.getPrincipal();
            if (user != null) {
                LOGGER.debug("请求路径为: [" + uri + "], 当前用户[" + user.getUserName() + "], 是否有权限: " + subject.isPermitted(uri));
            }
            if (subject.isPermitted(uri)) {
                return Boolean.TRUE;
            }
        }
    }
    return Boolean.FALSE;
}

@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

    Subject subject = getSubject(request, response);

    if (null == subject.getPrincipal()) {
        Map<String, String> resultMap = new HashMap<String, String>(16);
        resultMap.put("code", "1001");
        resultMap.put("message", "login first!");
        ShiroFilterUtils.out(response, resultMap);

    } else {

        Map<String, String> resultMap = new HashMap<String, String>(16);
        resultMap.put("code", "1002");
        resultMap.put("message", "no permission!");
        ShiroFilterUtils.out(response, resultMap);
    }
    return Boolean.FALSE;
}

}

这是我的境界

public class LoginRealm extends AuthorizingRealm {

/** logger */
private static final Logger LOGGER = LoggerFactory.getLogger(LoginRealm.class);

@Autowired
IPermissionService permissionService;

@Autowired
IUserService userService;


@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
        throws AuthenticationException {

    String username = (String) authenticationToken.getPrincipal();
    SysUser user = userService.getLoginUser(username);
    if (user == null) {
        throw new UnknownAccountException();
    }
    String password = user.getPassword();
    SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, ByteSource.Util.bytes(username + Constants.SALT), getName());

    return info;
}


@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    LOGGER.debug("Retrieving authorization information for {}", principalCollection);

    SysUser user = (SysUser) principalCollection.getPrimaryPrincipal();

    List<Permission> permissions = permissionService.findPermissionByLoginUserId(user.getId());


    List<String> permissionList = new ArrayList<>();
    for (Permission permission : permissions) {
        if (permission != null) {
            permissionList.add(permission.getPermissionUrl());
        }
    }

    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

    info.addStringPermissions(permissionList);

    return info;
}

}

这是东西:

当我登录系统时,会话将在30秒内失效。 因此,为解决此问题,我使SecurityManager与sessionManager关联,该会话管理器具有名称为“ SHIROCOOKIE”的simplecookie,而我遇到另一个问题是没有id []的会话。当我调用/ proGuard / project时会发生此问题/ getAll(当我尚未登录时)。

org.apache.shiro.session.UnknownSessionException: There is no session with id [5ce1d2ea-e92b-4e60-a9ec-9cc505af1b17]
at org.apache.shiro.session.mgt.eis.AbstractSessionDAO.readSession(AbstractSessionDAO.java:170)
at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSessionFromDataSource(DefaultSessionManager.java:236)
at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSession(DefaultSessionManager.java:222)
at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.doGetSession(AbstractValidatingSessionManager.java:118)
at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupSession(AbstractNativeSessionManager.java:148)
at org.apache.shiro.session.mgt.AbstractNativeSessionManager.getSession(AbstractNativeSessionManager.java:140)
at org.apache.shiro.mgt.SessionsSecurityManager.getSession(SessionsSecurityManager.java:156)
at org.apache.shiro.mgt.DefaultSecurityManager.resolveContextSession(DefaultSecurityManager.java:460)
at org.apache.shiro.mgt.DefaultSecurityManager.resolveSession(DefaultSecurityManager.java:446)
at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:342)
at org.apache.shiro.subject.Subject$Builder.buildSubject(Subject.java:845)
at org.apache.shiro.web.subject.WebSubject$Builder.buildWebSubject(WebSubject.java:148)
at org.apache.shiro.web.servlet.AbstractShiroFilter.createSubject(AbstractShiroFilter.java:292)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:359)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.jwkj.api.framework.page.filter.CORSFilter.doFilter(CORSFilter.java:29)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:285)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2431)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2420)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

我搜索过,但答案不匹配。像:Shiro expired session handlingShiro complaining "There is no session with id xxx" with DefaultSecurityManager

我试图按照源代码来解决它。我所知道的只是在 AbstractSessionDao readSession(Serializable sessionId) method中,s为null并且在执行doReadSession(sessionId)方法字段时ConcurrentMap会话的大小为0。我已经尽力了。期待您的帮助。非常感谢!

    public Session readSession(Serializable sessionId) throws UnknownSessionException {
    Session s = doReadSession(sessionId);
    if (s == null) {
        throw new UnknownSessionException("There is no session with id [" + sessionId + "]");
    }
    return s;
}

0 个答案:

没有答案