首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用表单身份验证进行身份验证

无法使用表单身份验证进行身份验证
EN

Stack Overflow用户
提问于 2020-05-29 16:03:18
回答 1查看 425关注 0票数 0

我很难弄清楚为什么我不能认证。在查看了跟踪之后,我认为会话没有被创建,也没有被清除,或者类似的东西。在我的Admin登录post方法中有一个代码块,如果没有注释身份验证工作,但是我不想手动这样做,因为Spring应该为我处理它。任何帮助将不胜感激,如果我可以包括更多的源代码,帮助,让我知道。

详细信息:

我使用的是Spring BootSpring SecurityThymleaf,并通过Localhost运行。

每次我在/admin/**上查看页面时,都会出现登录页面,并且需要提供凭据。当输入凭据时,登录页将处理和显示/admin/index (按照控制器),但是当我尝试导航到另一个页面(例如: /admin/orgs)时,登录屏幕将重新出现。除了显而易见的情况外,我知道用户没有经过身份验证,因为我检查用户是否在/admin/index上进行了身份验证。

项目结构

代码语言:javascript
复制
+ src
    + main
        + java
            - org.neric (package)
                - SecurityConfig
                - AdminController
                - AppController
                - Application
                - WebConfig
        + resources
            + templates
                - index.html 
                + admin
                    - index.html
                    - login.html
                    - orgs.html
            + static
                + css
                + js
                + img

Trace (application.properties trace=true)

代码语言:javascript
复制
2020-05-29 10:47:32.511 DEBUG 15316 --- [nio-8080-exec-1] o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@77ed1e40:org.apache.tomcat.util.net.NioChannel@78cb69e6:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:50574]], Read from buffer: [0]
2020-05-29 10:47:32.511 DEBUG 15316 --- [nio-8080-exec-1] org.apache.tomcat.util.net.NioEndpoint   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@77ed1e40:org.apache.tomcat.util.net.NioChannel@78cb69e6:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:50574]], Read direct from socket: [872]
2020-05-29 10:47:32.512 DEBUG 15316 --- [nio-8080-exec-1] o.a.t.util.http.Rfc6265CookieProcessor   : Cookies: Parsing b[]: sidenav-state=pinned; JSESSIONID=408BA31320628AA0E4E3E3D9FBEDC8DD
2020-05-29 10:47:32.512 DEBUG 15316 --- [nio-8080-exec-1] o.a.catalina.connector.CoyoteAdapter     :  Requested cookie session id is 408BA31320628AA0E4E3E3D9FBEDC8DD
2020-05-29 10:47:32.512 DEBUG 15316 --- [nio-8080-exec-1] o.a.c.authenticator.AuthenticatorBase    : Security checking request POST /admin/login
2020-05-29 10:47:32.512 DEBUG 15316 --- [nio-8080-exec-1] org.apache.catalina.realm.RealmBase      :   No applicable constraints defined
2020-05-29 10:47:32.512 DEBUG 15316 --- [nio-8080-exec-1] o.a.c.authenticator.AuthenticatorBase    :  Not subject to any constraint
2020-05-29 10:47:32.512 DEBUG 15316 --- [nio-8080-exec-1] o.apache.catalina.core.StandardWrapper   :   Returning non-STM instance
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] org.apache.tomcat.util.http.Parameters   : Set encoding to UTF-8
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] org.apache.tomcat.util.http.Parameters   : Start processing with input [%24%7B_csrf.parameterName%7D=%24%7B_csrf.token%7D&email=admin%40neric.org&password=123456]
2020-05-29 10:47:32.513 TRACE 15316 --- [nio-8080-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter  : Bound request context to thread: org.apache.catalina.connector.RequestFacade@2b59dd1c
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 4 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/admin/logout', GET]
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /admin/login' doesn't match 'GET /admin/logout'
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/admin/logout', POST]
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/admin/login'; against '/admin/logout'
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/admin/logout', PUT]
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /admin/login' doesn't match 'PUT /admin/logout'
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/admin/logout', DELETE]
2020-05-29 10:47:32.513 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'POST /admin/login' doesn't match 'DELETE /admin/logout'
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 5 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/admin/login'; against 'admin/login'
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.s.HttpSessionRequestCache        : saved request doesn't match
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@3bcd7783: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter'
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.session.SessionManagementFilter  : Requested session ID 408BA31320628AA0E4E3E3D9FBEDC8DD is invalid.
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Secure object: FilterInvocation: URL: /admin/login; Attributes: [permitAll]
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@3bcd7783: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.access.vote.AffirmativeBased       : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@2cf46161, returned: 1
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : Authorization successful
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.a.i.FilterSecurityInterceptor    : RunAsManager did not change Authentication object
2020-05-29 10:47:32.514 DEBUG 15316 --- [nio-8080-exec-1] o.s.security.web.FilterChainProxy        : /admin/login reached end of additional filter chain; proceeding with original chain
2020-05-29 10:47:32.514 TRACE 15316 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : POST "/admin/login", parameters={masked}, headers={masked} in DispatcherServlet 'dispatcherServlet'
2020-05-29 10:47:32.515 TRACE 15316 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'adminController'
2020-05-29 10:47:32.515 TRACE 15316 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public java.lang.String org.neric.AdminController.processForm(javax.servlet.http.HttpServletRequest,org.neric.bean.Login)
2020-05-29 10:47:32.515 TRACE 15316 --- [nio-8080-exec-1] o.s.web.cors.DefaultCorsProcessor        : Skip: request is from same origin
2020-05-29 10:47:32.516 TRACE 15316 --- [nio-8080-exec-1] .w.s.m.m.a.ServletInvocableHandlerMethod : Arguments: [SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.context.HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper@377af4f5], Login{email='admin@neric.org', password='123456'}]
Login{email='admin@neric.org', password='123456'}
2020-05-29 10:47:32.516 TRACE 15316 --- [nio-8080-exec-1] o.s.w.s.v.InternalResourceViewResolver   : View with key [admin/index] served from cache
2020-05-29 10:47:32.516 DEBUG 15316 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, application/signed-exchange;v=b3;q=0.9, */*;q=0.8]
2020-05-29 10:47:32.516 TRACE 15316 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Rendering view [org.thymeleaf.spring5.view.ThymeleafView@6137df47] 
2020-05-29 10:47:32.516 TRACE 15316 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'requestDataValueProcessor'
2020-05-29 10:47:32.520 TRACE 15316 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'webSecurityExpressionHandler'
2020-05-29 10:47:32.520 TRACE 15316 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory     : Returning cached instance of singleton bean 'webSecurityExpressionHandler'
2020-05-29 10:47:32.522 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@5b0bf2c9
2020-05-29 10:47:32.522 DEBUG 15316 --- [nio-8080-exec-1] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-05-29 10:47:32.523 DEBUG 15316 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed 200 OK, headers={masked}
2020-05-29 10:47:32.523 DEBUG 15316 --- [nio-8080-exec-1] o.s.s.w.a.ExceptionTranslationFilter     : Chain processed normally
2020-05-29 10:47:32.523 DEBUG 15316 --- [nio-8080-exec-1] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2020-05-29 10:47:32.523 TRACE 15316 --- [nio-8080-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter  : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@2b59dd1c
2020-05-29 10:47:32.523 DEBUG 15316 --- [nio-8080-exec-1] o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@77ed1e40:org.apache.tomcat.util.net.NioChannel@78cb69e6:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:50574]], Read from buffer: [0]
2020-05-29 10:47:32.523 DEBUG 15316 --- [nio-8080-exec-1] org.apache.tomcat.util.net.NioEndpoint   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@77ed1e40:org.apache.tomcat.util.net.NioChannel@78cb69e6:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:50574]], Read direct from socket: [0]

POM

代码语言:javascript
复制
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        <version>3.0.4.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
<dependencies>

应用程序

代码语言:javascript
复制
@EnableScheduling
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

SecurityConfig

代码语言:javascript
复制
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user@neric.org")
                .password(passwordEncoder().encode("123456"))
                .roles("USER")
            .and()
                .withUser("admin@neric.org")
                    .password(passwordEncoder().encode("123456"))
                    .roles("ADMIN");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http
        .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
        .and()
            .formLogin()
                .loginPage("/admin/login")
                    .usernameParameter("email")
                    .passwordParameter("password")
                .loginProcessingUrl("admin/login") //dont change, it's not the same as the line above.... /smh...
                .failureUrl("/404")
            .permitAll()
        .and()
            .logout()
                .logoutUrl("/admin/logout")
                .invalidateHttpSession(true)
            .permitAll()
        .and()
            .csrf()
                .disable()
        //.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
       ;
    }
}

WebConfig

代码语言:javascript
复制
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/webjars/**", "/img/**", "/css/**", "/js/**")
            .addResourceLocations("classpath:/META-INF/resources/webjars/", "classpath:/static/img/", "classpath:/static/css/", "classpath:/static/js/")
        ;
    }

}

AdminController

代码语言:javascript
复制
@Controller
public class AdminController {

    @GetMapping("/admin/logout")
    public String logout(Login login) {
        return "admin/login";
    }

    @PostMapping("/admin/logout")
    public String logoutPost(Login login) {
        return "admin/login";
    }

    @GetMapping("/admin/login")
    public String login(Login login) {
        return "admin/login";
    }

    @PostMapping("/admin/login")
    public String processForm(HttpServletRequest req, Login login)  {
        System.out.println(login);

        /* If I uncomment this, I can force authentication. Though, I shouldn't have to
        UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(login.getEmail(), login.getPassword());
        Authentication auth = authManager.authenticate(authReq);

        SecurityContext sc = SecurityContextHolder.getContext();
        sc.setAuthentication(auth);
        HttpSession session = req.getSession(true);
        session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, sc);*/

        return "admin/index";
    }

    @GetMapping("/admin")
    public String showAdmin() {
        return "admin/index";
    }

    @GetMapping("/admin/orgs")
    public String showOrgs(Organization organization) {
        return "admin/orgs";
    }
}

/admin/login (/resources/templates/admin/login.html)

代码语言:javascript
复制
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org"
  xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
  lang="en">

<head>
    <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" />
    <link rel="stylesheet" th:href="@{/css/all.min.css}" />
    <link rel="stylesheet" th:href="@{/css/login.css}" />

</head>
<body>
    <div class="app-container app-theme-white body-tabs-shadow">
        <div class="app-container">
            <div class="h-100 bg-animation">
                <div class="d-flex h-100 justify-content-center align-items-center">
                    <div class="mx-auto app-login-box col-md-8">
                        <div class="app-logo mx-auto mb-3"></div>

                        <form th:action="@{/admin/login}" th:object="${login}" method="post" class="needs-validation" novalidate>
                            <div class="modal-dialog w-100 mx-auto">
                                <div class="modal-content">
                                    <div class="modal-body">
                                        <div class="h5 modal-title text-center">
                                            <h4 class="mt-2">
                                                <div>Welcome back,</div>
                                                <span>Please sign in to your account below.</span>
                                            </h4>
                                        </div>

                                            <div class="form-row">
                                                <div class="col-md-12">
                                                    <div class="position-relative form-group">
                                                        <input name="email" id="exampleEmail" placeholder="Email here..." type="email" class="form-control" th:field="*{email}" required>
                                                    </div>
                                                </div>
                                                <div class="col-md-12">
                                                    <div class="position-relative form-group">
                                                        <input name="password" id="examplePassword" placeholder="Password here..." type="password" class="form-control" th:field="*{password}" required>
                                                    </div>
                                                </div>
                                            </div>
                                    </div>
                                    <div class="modal-footer clearfix">
                                        <div class="float-left">
                                            <a href="javascript:void(0);" class="btn-lg btn btn-link">Recover Password</a> <!--TODO-->
                                        </div>
                                        <div class="float-right">
                                            <button class="btn btn-primary btn-lg" type="submit">Login</button>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </form>
                        <div class="text-center text-black opacity-8 mt-3" th:text="'Copyright © Capital Region BOCES ' + ${#dates.year(#dates.createNow())}"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script th:src="@{/js/jquery.min.js}"></script>
    <script th:src="@{/js/bootstrap.bundle.min.js}"></script>
    <script>
        (function() {
            'use strict';

            window.addEventListener('load', function() {
                // Fetch all the forms we want to apply custom Bootstrap validation styles to
                var forms = document.getElementsByClassName('needs-validation');

                // Loop over them and prevent submission
                var validation = Array.prototype.filter.call(forms, function(form) {
                    form.addEventListener('submit', function(event) {
                        if (form.checkValidity() === false) {
                            event.preventDefault();
                            event.stopPropagation();
                        }
                        form.classList.add('was-validated');
                    }, false);
                });
            }, false);
        })();
    </script>

</body>

管理/索引(/resources//admin/index.html)

重要部分

代码语言:javascript
复制
    <div sec:authorize="isAuthenticated()">
        Authenticated
    </div>
    <div sec:authorize="!isAuthenticated()">
        Not authenticated
    </div>

整页

代码语言:javascript
复制
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security" lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- Favicon -->
    <link rel="icon" href="../../assets/img/brand/favicon.png" type="image/png">
    <!-- Fonts -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700">
    <!-- Icons -->
    <link rel="stylesheet" th:href="@{/css/nucleo.css}" />
    <link rel="stylesheet" th:href="@{/css/all.min.css}" />
    <!-- Argon CSS -->
    <link rel="stylesheet" th:href="@{/css/argon.css}" />
    <!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">-->
</head>

<body class="docs">
<header class="navbar navbar-horizontal navbar-expand navbar-dark flex-row align-items-md-center ct-navbar">
    <a class="navbar-brand mr-0 mr-md-2" th:href="@{/admin/}" aria-label="Admin">
        <img src="https://www.capitalregionboces.org/wp-content/themes/twentyseventeen-child/images/crb-logo-header.svg">
        <sup>Admin</sup>
    </a>
</header>
<div class="container-fluid">
    <div class="row flex-xl-nowrap">
        <div class="col-12 col-md-3 col-xl-2 ct-sidebar">
            <nav class="collapse ct-links" id="ct-docs-nav">
                <!-- Show links for all groups -->
                <div class="ct-toc-item active">
                    <a class="ct-toc-link" href="../../docs/getting-started/overview.html">Manage</a>
                    <ul class="nav ct-sidenav">
                        <li class="active ct-sidenav-active">
                            <a th:href="@{/admin/orgs}">Organizations</a>
                        </li>
                        <li>
                            <a th:href="@{/admin/buildings}">Buildings</a>
                        </li>
                        <li>
                            <a th:href="@{/admin/roles}">Roles</a>
                        </li>
                    </ul>
                </div>
                <!-- Show links for all groups -->
                <div class="ct-toc-item active">
                    <a class="ct-toc-link" href="../../docs/foundation/colors.html">Reports</a>
                    <ul class="nav ct-sidenav">
                        <li>
                            <a th:href="@{/admin/reports/dailyUsage}">Daily Usage</a>
                        </li>
                    </ul>
                </div>

            </nav>
        </div>

        <!-- Main Content: Side Bar -->
        <div class="d-none d-xl-block col-xl-2 ct-toc">
            <ul class="section-nav">
                <li class="toc-entry toc-h3"><a th:href="@{/admin/orgs/add}">Add Organization</a></li>
            </ul>
        </div>

        <main class="col-12 col-md-8 col-xl-7 py-md-3 pl-md-5 ct-content" role="main">
            <!-- Main Content: Header -->
            <div class="ct-page-title">
                <h1 class="ct-title" id="content">Index</h1>
                <div class="avatar-group mt-3"></div>
            </div>
            <!--<p class="ct-lead">A list of all the organizations.</p>-->

            <hr>

            <!-- Main Content -->

            <div sec:authorize="isAuthenticated()">
                Authenticated
            </div>

            <div sec:authorize="!isAuthenticated()">
                Not authenticated
            </div>

            <!-- End Main Content -->

        </main>
    </div>
</div>
<!-- Core -->
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/bootstrap.bundle.min.js}"></script>
<script th:src="@{/js/js.cookie.js}"></script>
<script th:src="@{/js/jquery.scrollbar.min.js}"></script>
<script th:src="@{/js/jquery-scrollLock.min.js}"></script>
<!-- Docs JS -->
<script th:src="@{/js/anchor.min.js}"></script>
<script th:src="@{/js/clipboard.min.js}"></script>
<script th:src="@{/js/holder.min.js}"></script>
<script th:src="@{/js/prism.js}"></script>
<!-- Argon JS -->
<script th:src="@{/js/argon.min.js}"></script>
</body>

</html>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-29 18:03:22

问题在您的安全配置中。

你在保护一切。见下文。

代码语言:javascript
复制
http
    .authorizeRequests()
        .antMatchers("/admin/**").hasRole("ADMIN")

所以它会让你一次又一次地发送登录页面。因为它没有成功通过安全过滤器。

我建议将控制器映射更改为@GetMapping("/login"),并通过添加以下配置更改使每个人都可以访问该映射。

代码语言:javascript
复制
 @Override
protected void configure(HttpSecurity http) throws Exception {
   http
    .authorizeRequests().antMatchers("/login").permitAll()
        .antMatchers("/admin/**").hasRole("ADMIN")
    .and()
        .formLogin().loginPage("/login") // cutom login page. 
        .usernameParameter("email")
        .passwordParameter("password")
        .loginProcessingUrl("/login")  // this should be public too(which we did) as user's request would reach here then authentication will happen. 
        .defaultSuccessUrl("/loginSuccess") // this has to be done since you have two different role so we need to identify whether user role or admin role and based on that redirection should happen.
    .and()
        .logout()
            .logoutUrl("/logout") // logout should be common for both roles so don't add /admin/logout  
             .invalidateHttpSession(true)
        .permitAll()
    .and()
        .csrf()
            .disable()
    //.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
   ;
}

这里是控制器:

代码语言:javascript
复制
@Controller 
public class AdminController {
@GetMapping("/login")
public String login() {
    return "admin/login";
}
@GetMapping("/loginSuccess")
public String showAdmin(@AuthenticationPrincipal User userDetails) {
    // check the role if user then redirect to user page, if admin then redirect to admin page. 
    List<GrantedAuthority> authorties = userDetails.getAuthorities().stream().collect(Collectors.toList());

    boolean isAdmin=false;
    if(authorties.stream().anyMatch(p->p.getAuthority().equals("ROLE_ADMIN"))) {
        return "admin/index";
    } else {
        return "user/index";
    }
}

}

结帐工作代码这里

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62090104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档