Shiro filter authentication user error when user h

2019-08-09 04:40发布

问题:

When I'm using AJAX and attempt to login I get a server response code 200 but when I try to access another URL, the Shiro filter always intercepts my request.

I'm configuring the filter in the spirng-shiro.xml.

This shows the user access, login is ok but the other url gets a 302: get list url

function loginUser() {
    axios.post(`${FOO_API}/login`, {
        name: "foo",
        passwd: "123456"
    });
    console.log("1");
}

function getUserIndex() {
    axios.get(`${FOO_API}/list`);
}

Server controller, redundant code omitted:

@RequestMapping("/login")
public JsonResult login(@RequestBody Map<String, Object> map, HttpServletRequest request) {
    Subject currentUser = SecurityUtils.getSubject();
    String name = map.get("name").toString();
    String md5Pwd = new Md5Hash(map.get("passwd").toString(), name).toString();
    if (!currentUser.isAuthenticated()) {
        UsernamePasswordToken token = new UsernamePasswordToken(name, md5Pwd);
        token.setRememberMe(true);
        try {
            currentUser.login(token);
            log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
        } catch (UnknownAccountException uae) {
            uae.printStackTrace();
        } catch (AuthenticationException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return JsonResult.createSuccess("ok");
}

@GetMapping("/list")
public JsonResult getAll(HttpServletRequest request, HttpServletResponse response) {
    Subject subject = SecurityUtils.getSubject();
    System.out.println("user name: " + subject.getPrincipal());
    Cookie[] cookies = request.getCookies();
    for (Cookie cookie : cookies) {
        System.out.println("cookie name: " + cookie.getName());
        System.out.println("cookie val: " + cookie.getValue());
    }
    return JsonResult.createSuccess(userService.getAll());
}

Spring-Shiro config, I'm only configuring one realm extending AuthorizingRealm and implementing one authentication method:

<bean id="shiroFilter"
    class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager" />
    <property name="loginUrl" value="/api/users/login" />
    <property name="successUrl" value="/api/users/index" />
    <property name="unauthorizedUrl" value="/unauthorized.jsp" />
    <property name="filterChainDefinitions">
        <value>
            /api/users/login = anon
            /api/users/doLogin = anon
            /api/users/logout = anon
            /api/users/** = authc
        </value>
    </property>
</bean>

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    System.out.println("get two");
    UsernamePasswordToken upToken = (UsernamePasswordToken) token;
    Map<String, Object> map = Maps.newHashMap();
    String name = upToken.getUsername();
    map.put("name", name);
    User user = null;
    try {
        user = getUserService().login(map);
    } catch (Exception e) {
        System.out.println("catch me");
        e.printStackTrace();
    }
    if (user != null)
        return new SimpleAuthenticationInfo(user.getName(), user.getPasswd(), getName());
    return null;
}

update: change filterChainDefinitions value

    ....
    <property name="filterChainDefinitions">
        <value>
            /assets/** = anon
            /api/users/login = authc
            /api/users/logout = logout
            /api/users/** = authc
        </value>
    </property>
   ....

user login OK. It will take another method be invoked when request /api/users/login

only login method make error when first login, just invoke this error method will be get real /api/users/login

trigger another method error

full message

11:54:39.881 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'springmvc' processing OPTIONS request for [/api/users/login]
11:54:39.881 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /api/users/login
11:54:39.882 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Returning handler method [public com.f.util.JsonResult com.f.api.controller.UserController.login(java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest)]
11:54:39.882 [http-nio-8080-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'userController'
11:54:39.883 [http-nio-8080-exec-3] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected element of bean 'userController': ResourceElement for public com.f.service.UserService com.f.api.controller.UserController.userService
11:54:39.883 [http-nio-8080-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'api.userService'
11:54:39.883 [http-nio-8080-exec-3] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected element of bean 'api.userService': AutowiredFieldElement for private com.f.dao.UserMapper com.f.service.impl.UserServiceImpl.userMapper
11:54:39.883 [http-nio-8080-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userMapper'
11:54:39.883 [http-nio-8080-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
11:54:39.883 [http-nio-8080-exec-3] DEBUG org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator - Creating implicit proxy for bean 'api.userService' with 0 common interceptors and 1 specific interceptors
11:54:39.883 [http-nio-8080-exec-3] DEBUG org.springframework.aop.framework.CglibAopProxy - Creating CGLIB proxy: target source is SingletonTargetSource for target object [com.f.service.impl.UserServiceImpl@73316c84]
11:54:39.884 [http-nio-8080-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'api.userService'
11:54:39.884 [http-nio-8080-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'userController'
11:54:39.923 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'springmvc': assuming HandlerAdapter completed request handling
11:54:39.924 [http-nio-8080-exec-3] DEBUG org.springframework.web.servlet.DispatcherServlet - Successfully completed request
11:54:39.947 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [com.f.service.impl.UserServiceImpl.login]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
11:54:39.948 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [HikariProxyConnection@1099897330 wrapping com.mysql.cj.jdbc.ConnectionImpl@399b2ef] for JDBC transaction
11:54:39.948 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [HikariProxyConnection@1099897330 wrapping com.mysql.cj.jdbc.ConnectionImpl@399b2ef] to manual commit
11:54:39.950 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
11:54:39.950 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4f48efb3]
11:54:39.951 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [HikariProxyConnection@1099897330 wrapping com.mysql.cj.jdbc.ConnectionImpl@399b2ef] will be managed by Spring
11:54:39.951 [http-nio-8080-exec-4] DEBUG com.f.dao.UserMapper.login - ==>  Preparing: select u.id, u.name, u.passwd, p.id p_id, p.project_name from users u left outer join project p on p.id = u.project_id 
11:54:39.951 [http-nio-8080-exec-4] DEBUG com.f.dao.UserMapper.login - ==> Parameters: 
11:54:39.959 [http-nio-8080-exec-4] DEBUG com.f.dao.UserMapper.login - <==      Total: 19
11:54:39.960 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4f48efb3]
11:54:39.961 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4f48efb3]
11:54:39.962 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4f48efb3]
11:54:39.963 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Initiating transaction rollback
11:54:39.963 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [HikariProxyConnection@1099897330 wrapping com.mysql.cj.jdbc.ConnectionImpl@399b2ef]
11:54:39.964 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [HikariProxyConnection@1099897330 wrapping com.mysql.cj.jdbc.ConnectionImpl@399b2ef] after transaction
11:54:39.964 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 19
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
    at com.sun.proxy.$Proxy84.selectOne(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:166)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:83)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
    at com.sun.proxy.$Proxy103.login(Unknown Source)
    at com.f.service.impl.UserServiceImpl.login(UserServiceImpl.java:26)
    at com.f.service.impl.UserServiceImpl$$FastClassBySpringCGLIB$$79b2f5ea.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
    at com.f.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$3e9f3d2c.login(<generated>)
    at com.f.security.MyRealm.doGetAuthenticationInfo(MyRealm.java:61)
    at org.apache.shiro.realm.AuthenticatingRealm.getAuthenticationInfo(AuthenticatingRealm.java:571)
    at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doSingleRealmAuthentication(ModularRealmAuthenticator.java:180)
    at org.apache.shiro.authc.pam.ModularRealmAuthenticator.doAuthenticate(ModularRealmAuthenticator.java:267)
    at org.apache.shiro.authc.AbstractAuthenticator.authenticate(AbstractAuthenticator.java:198)
    at org.apache.shiro.mgt.AuthenticatingSecurityManager.authenticate(AuthenticatingSecurityManager.java:106)
    at org.apache.shiro.mgt.DefaultSecurityManager.login(DefaultSecurityManager.java:274)
    at org.apache.shiro.subject.support.DelegatingSubject.login(DelegatingSubject.java:260)
    at org.apache.shiro.web.filter.authc.AuthenticatingFilter.executeLogin(AuthenticatingFilter.java:53)
    at org.apache.shiro.web.filter.authc.FormAuthenticationFilter.onAccessDenied(FormAuthenticationFilter.java:154)
    at org.apache.shiro.web.filter.AccessControlFilter.onAccessDenied(AccessControlFilter.java:133)
    at org.apache.shiro.web.filter.AccessControlFilter.onPreHandle(AccessControlFilter.java:162)
    at org.apache.shiro.web.filter.PathMatchingFilter.isFilterChainContinued(PathMatchingFilter.java:203)
    at org.apache.shiro.web.filter.PathMatchingFilter.preHandle(PathMatchingFilter.java:178)
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:131)
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
    at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
    at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
    at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
    at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
    at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 19
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:81)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
    ... 63 more
11:54:39.976 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'springmvc' processing POST request for [/api/users/login]
11:54:39.977 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /api/users/login
11:54:39.977 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Returning handler method [public com.f.util.JsonResult com.f.api.controller.UserController.login(java.util.Map<java.lang.String, java.lang.Object>,javax.servlet.http.HttpServletRequest)]
11:54:39.978 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'userController'
11:54:39.978 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected element of bean 'userController': ResourceElement for public com.f.service.UserService com.f.api.controller.UserController.userService
11:54:39.979 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'api.userService'
11:54:39.980 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected element of bean 'api.userService': AutowiredFieldElement for private com.f.dao.UserMapper com.f.service.impl.UserServiceImpl.userMapper
11:54:39.980 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userMapper'
11:54:39.980 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
11:54:39.980 [http-nio-8080-exec-4] DEBUG org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator - Creating implicit proxy for bean 'api.userService' with 0 common interceptors and 1 specific interceptors
11:54:39.980 [http-nio-8080-exec-4] DEBUG org.springframework.aop.framework.CglibAopProxy - Creating CGLIB proxy: target source is SingletonTargetSource for target object [com.f.service.impl.UserServiceImpl@4f22ef0e]
11:54:39.981 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'api.userService'
11:54:39.981 [http-nio-8080-exec-4] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'userController'
11:54:39.983 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor - Read [java.util.Map<java.lang.String, java.lang.Object>] as "application/json;charset=UTF-8" with [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@50be15cd]
11:54:39.984 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [com.f.service.impl.UserServiceImpl.login]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
11:54:39.984 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [HikariProxyConnection@1851398855 wrapping com.mysql.cj.jdbc.ConnectionImpl@399b2ef] for JDBC transaction
11:54:39.984 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [HikariProxyConnection@1851398855 wrapping com.mysql.cj.jdbc.ConnectionImpl@399b2ef] to manual commit
11:54:39.986 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Creating a new SqlSession
11:54:39.987 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@386927e4]
11:54:39.987 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [HikariProxyConnection@1851398855 wrapping com.mysql.cj.jdbc.ConnectionImpl@399b2ef] will be managed by Spring
11:54:39.987 [http-nio-8080-exec-4] DEBUG com.f.dao.UserMapper.login - ==>  Preparing: select u.id, u.name, u.passwd, p.id p_id, p.project_name from users u left outer join project p on p.id = u.project_id WHERE name = ? 
11:54:39.999 [http-nio-8080-exec-4] DEBUG com.f.dao.UserMapper.login - ==> Parameters: foo(String)
11:54:40.010 [http-nio-8080-exec-4] DEBUG com.f.dao.UserMapper.login - <==      Total: 1
11:54:40.010 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@386927e4]
11:54:40.011 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@386927e4]
11:54:40.011 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@386927e4]
11:54:40.011 [http-nio-8080-exec-4] DEBUG org.mybatis.spring.SqlSessionUtils - Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@386927e4]
11:54:40.011 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Initiating transaction commit
11:54:40.011 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Committing JDBC transaction on Connection [HikariProxyConnection@1851398855 wrapping com.mysql.cj.jdbc.ConnectionImpl@399b2ef]
11:54:40.014 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [HikariProxyConnection@1851398855 wrapping com.mysql.cj.jdbc.ConnectionImpl@399b2ef] after transaction
11:54:40.014 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
11:54:40.017 [http-nio-8080-exec-4] INFO  com.f.api.controller.UserController - User [foo] logged in successfully.
11:54:40.018 [http-nio-8080-exec-4] INFO  com.f.api.controller.UserController - "foo"
11:54:40.021 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor - Written [com.f.util.JsonResult@1f8078e2] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@50be15cd]
11:54:40.021 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'springmvc': assuming HandlerAdapter completed request handling
11:54:40.021 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.DispatcherServlet - Successfully completed request

回答1:

You are not actually logging in into your application and no session cookie is registered since you are using two completely different filters. Your login path is set to anon, discarding whatever you post to it, but your protected resource path is using the authc filter which requires the caller to be authorized or authorize now.

What currently is happening in your application is that when you are calling api/users/list Shiro is redirecting you to api/users/login since you are not authorized. It is expecting you to perform a POST, presenting your username and password, but receiving a GET, resulting in a 302 method not allowed.

The correct approach for a form-based login is to point your login path and your protected resource paths to the authc filter and the logout path to the logout filter. You can read more about default filters and how to use them in the official Shiro documentation.

The following snipped should point your paths to the correct filters:

....
<property name="filterChainDefinitions">
    <value>
        /api/users/login = authc
        /api/users/logout = logout
        /api/users/** = authc
    </value>
</property>
....