我很难弄清楚为什么我不能认证。在查看了跟踪之后,我认为会话没有被创建,也没有被清除,或者类似的东西。在我的Admin登录post方法中有一个代码块,如果没有注释身份验证工作,但是我不想手动这样做,因为Spring应该为我处理它。任何帮助将不胜感激,如果我可以包括更多的源代码,帮助,让我知道。
详细信息:
我使用的是Spring Boot、Spring Security、Thymleaf,并通过Localhost运行。
每次我在/admin/**上查看页面时,都会出现登录页面,并且需要提供凭据。当输入凭据时,登录页将处理和显示/admin/index (按照控制器),但是当我尝试导航到另一个页面(例如: /admin/orgs)时,登录屏幕将重新出现。除了显而易见的情况外,我知道用户没有经过身份验证,因为我检查用户是否在/admin/index上进行了身份验证。
项目结构
+ 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
+ imgTrace (application.properties trace=true)
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
<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>应用程序
@EnableScheduling
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}SecurityConfig
@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
@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
@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)
<!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)
重要部分
<div sec:authorize="isAuthenticated()">
Authenticated
</div>
<div sec:authorize="!isAuthenticated()">
Not authenticated
</div>整页
<!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>发布于 2020-05-29 18:03:22
问题在您的安全配置中。
你在保护一切。见下文。
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")所以它会让你一次又一次地发送登录页面。因为它没有成功通过安全过滤器。
我建议将控制器映射更改为@GetMapping("/login"),并通过添加以下配置更改使每个人都可以访问该映射。
@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)
;
}这里是控制器:
@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";
}
}}
结帐工作代码这里
https://stackoverflow.com/questions/62090104
复制相似问题