簡體   English   中英

Spring security 只顯示登錄頁面的標題

[英]Spring security only shows header of login page

我一直在與這個搏斗一段時間。

我有一個 Web 應用程序,我試圖將 Spring Security 放入其中。 我已經成功地做到了,每當用戶嘗試訪問他們未被授權的頁面時,它都會將他們重定向到登錄頁面。 問題是登錄頁面沒有顯示 - 只是登錄頁面的標題(並且沒有風格化)。 我對此感到非常困惑,因為所有其他頁面都顯示正常。

這是我正在工作的示例,我非常努力地遵循它甚至下載了它,但我無法完全看到我在自己的項目中所做的不同。

我看到的唯一大區別是我使用的是 Gradle 而這個人使用的是 Maven。

這是我的 build.gradle:

 buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.7.RELEASE") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' apply plugin: 'org.springframework.boot' jar { baseName = 'gs-spring-boot' baseName = 'gs-handling-form-submission' baseName = 'gs-serving-mobile-web-content' baseName = 'gs-accessing-data-mongodb' baseName = 'gs-rest-service-cors' baseName = 'gs-securing-web' version = '0.1.0' } repositories { mavenCentral() } sourceCompatibility = 1.8 targetCompatibility = 1.8 dependencies { compile("org.springframework.boot:spring-boot-starter-web") { exclude module: "spring-boot-starter-tomcat" } compile("org.springframework.boot:spring-boot-starter-jetty") testCompile("org.springframework.boot:spring-boot-starter-test") compile("org.springframework.boot:spring-boot-starter-actuator") testCompile 'junit:junit:4.12' compile("org.springframework.boot:spring-boot-starter-data-mongodb") compile group: 'joda-time', name: 'joda-time', version: '2.8.1' compile("org.springframework.boot:spring-boot-starter-web:1.3.0.RELEASE") compile 'org.slf4j:slf4j-api:1.7.13' compile("org.springframework.boot:spring-boot-starter-web") compile("org.springframework.boot:spring-boot-parent:1.5.3.RELEASE") compile("org.springframework.boot:spring-boot-starter-thymeleaf") compile("org.springframework.boot:spring-boot-starter-data-mongodb") compile("org.springframework.boot:spring-boot-starter-mobile") compile("org.springframework.boot:spring-boot-starter-data-jpa") compile("com.h2database:h2") compile("net.sourceforge.nekohtml:nekohtml:1.9.21") compile("org.springframework.boot:spring-boot-starter-data-mongodb:1.2.0.RELEASE") compile("org.springframework.boot.spring-boot-starter-remote-shell:1.2.0.RELEASE") compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity4") compile("org.springframework.boot:spring-boot-devtools:true") testCompile("org.springframework.security:spring-security-test") compile("org.springframework.boot:spring-boot-starter-security") }

這是我的控制器:

 @Controller public class WebController { //implements ErrorController{ private static final String PATH = "/error"; private BlogPostRepo blogPostRepo; @Autowired public WebController(BlogPostRepo blogPostRepo) { this.blogPostRepo = blogPostRepo; } @RequestMapping("/index") public String displayBlogPosts(Model model){ model.addAttribute("blogPosts", blogPostRepo.findAll()); return "index"; } @RequestMapping("/login") public String login(){ return "/login"; } @GetMapping("/403") public String error403() { return "/error/403"; } }

這是 SpringSecurityConfig.java :

 package com.stereoscopics.app.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.web.access.AccessDeniedHandler; @Configuration // http://docs.spring.io/spring-boot/docs/current/reference/html/howto-security.html // Switch off the Spring Boot security configuration //@EnableWebSecurity public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private AccessDeniedHandler accessDeniedHandler; // roles admin allow to access /admin/** // roles user allow to access /user/** // custom 403 access denied handler @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/", "/index", "/submitAnArticle").permitAll() .antMatchers("/admin/**").hasAnyRole("ADMIN") .antMatchers("/user/**").hasAnyRole("USER") .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll() .and() .exceptionHandling().accessDeniedHandler(accessDeniedHandler); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("password").roles("USER") .and() .withUser("admin").password("password").roles("ADMIN"); } }

這是我的 AccessDeniedHandler.java:

 package com.stereoscopics.app.error; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.stereotype.Component; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; // handle 403 page @Component public class MyAccessDeniedHandler implements AccessDeniedHandler { private static Logger logger = LoggerFactory.getLogger(MyAccessDeniedHandler.class); @Override public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null) { logger.info("User '" + auth.getName() + "' attempted to access the protected URL: " + httpServletRequest.getRequestURI()); } httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/403"); } }

這是我的登錄信息:

 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" > <head> <title>Spring Security Example </title> <div th:replace="fragments/header :: header-css"/> </head> <body> <div th:replace="fragments/header :: header"/> <div class="container"> <div class="row" style="margin-top:20px"> <div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3"> <form th:action="@{/login}" method="post"> <fieldset> <h1>Please Sign In</h1> <div th:if="${param.error}"> <div class="alert alert-danger"> Invalid username and password. </div> </div> <div th:if="${param.logout}"> <div class="alert alert-info"> You have been logged out. </div> </div> <div class="form-group"> <input type="text" name="username" id="username" class="form-control input-lg" placeholder="UserName" required="true" autofocus="true"/> </div> <div class="form-group"> <input type="password" name="password" id="password" class="form-control input-lg" placeholder="Password" required="true"/> </div> <div class="row"> <div class="col-xs-6 col-sm-6 col-md-6"> <input type="submit" class="btn btn-lg btn-primary btn-block" value="Sign In"/> </div> <div class="col-xs-6 col-sm-6 col-md-6"> </div> </div> </fieldset> </form> </div> </div> </div> <div th:replace="fragments/footer :: footer"/> </body> </html>

這是我的標題:

 <html xmlns:th="http://www.thymeleaf.org"> <head> <div th:fragment="header-css"> <!-- this is header-css --> <link rel="stylesheet" type="text/css" href="webjars/bootstrap/3.3.7/css/bootstrap.min.css" /> <link rel="stylesheet" th:href="@{/css/main.css}" href="../../css/main.css" /> </div> </head> <body> <div th:fragment="header"> <!-- this is header --> <nav class="navbar navbar-inverse"> <div class="container"> <div class="navbar-header"> <a class="navbar-brand" th:href="@{/}">Spring Boot</a> </div> <div id="navbar" class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li class="active"><a th:href="@{/}">Home</a></li> </ul> </div> </div> </nav> </div> </body> </html>

這是我嘗試過的:

檢查文件路徑 - 頁眉和頁腳在 \\resources\\templates\\fragments 中,其他文件在 resources\\templates

谷歌(找不到任何東西)

仔細檢查依賴項

下載示例並交叉檢查

我很困惑,很困惑。 請幫忙。

如果沒有可運行的示例(我可以克隆的 git 存儲庫會很好),很難調試,但我看到的一件事是您的安全配置需要身份驗證才能訪問樣式表。

添加

.antMatchers("/webjars/**").permitAll()
.antMatchers("/css/**").permitAll()

到您的安全配置,樣式表應該加載。

此外,您可能應該在標題中使用樣式表的絕對路徑,因為../../css/main.css可能不適用於您的所有 URL。

調試這些東西的一個好方法是使用瀏覽器中的 Web 控制台並查看網絡請求並查看是否所有資產都正確加載。

您確定您的登錄頁面顯示不正確嗎? 我相信您可能將未正確驗證的請求重定向到錯誤的頁面。 當您處理在 MyAccessDeniedHandler 類中被拒絕的請求時,您將執行以下操作:

httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/403");

這又由 WebController 類使用以下代碼處理:

@GetMapping("/403")
public String error403() {
    return "/error/403";
}

因此,當您處理 403 時,似乎您實際上並未呈現登錄頁面。

我對 thyme Leaf 不熟悉,但我的猜測是你沒有定義 error/403 文件,即使渲染頁面時找不到 html 文件,也會渲染標題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM