我在我的Spring Boot应用程序中使用Spring Security,似乎Thymeleaf授权无法正常工作。
我有一个带有以下代码的Thymeleaf模板:
<div class="container">
<div class="row" sec:authorize="isAuthenticated()">
<h2 style="color:green">User is Logged In</h2>
<p sec:authentication="principal.username">username</p>
</div>
<div class="row" sec:authorize="!isAuthenticated()">
<h2 style="color:red">User is Logged Out</h2>
</div>
<div class="row" sec:authorize="hasRole('ROLE_SUPERUSER')">
<h2>This will only be displayed if authenticated user has role ROLE_SUPERUSER.</h2>
</div>
<div class="row" sec:authorize="hasRole('ROLE_ADMIN')">
<h2>This will only be displayed if authenticated user has role ROLE_ADMIN.</h2>
</div>
<div class="row" sec:authorize="hasRole('ROLE_USER')">
<h2>This will only be displayed if authenticated user has role ROLE_USER.</h2>
</div>
<div th:if="${#authorization.expression('hasRole(''ROLE_ADMIN'')')}">
This will only be displayed if authenticated user has role ROLE_ADMIN.
</div>
<div th:if="${#authorization.expr('hasRole(''ROLE_ADMIN'')')}">
This will only be displayed if authenticated user has role ROLE_ADMIN.
</div>
</div>
举例如下:https://github.com/thymeleaf/thymeleaf-extras-springsecurity
但是,显示的唯一内容是sec:authorize=“isAuthenticated()”
和sec:authorize=“!isAuthenticated()”
,并且无论用户的角色如何,授权始终被忽略。
我的胸腺配置是:
@Configuration
public class ThymeleafConfig {
@Bean
public TemplateResolver defaultTemplateResolver() {
TemplateResolver resolver = new TemplateResolver();
resolver.setResourceResolver(thymeleafResourceResolver());
resolver.setPrefix("classpath:/templates/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF-8");
resolver.setCacheable(true);
return resolver;
}
@Bean
public SpringResourceResourceResolver thymeleafResourceResolver() {
return new SpringResourceResourceResolver();
}
@Bean
public SpringTemplateEngine templateEngine(TemplateResolver templateResolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(templateResolver);
engine.addDialect(new SpringSecurityDialect());
engine.addDialect(new LayoutDialect());
return engine;
}
@Bean
public ThymeleafViewResolver thymeleafViewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine);
resolver.setCharacterEncoding("UTF-8");
resolver.setContentType("text/html");
resolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
return resolver;
}
}
我对thymeleaf-extras-springsecurity4
使用以下依赖项:
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
版本<代码>3.0.2。RELEASE根本不起作用,sec
命名空间总是被Thymeleaf忽略
我的Spring Boot版本是1.5.2。发布
。
原因可能是什么?
使现代化SecurityConfig
中的configure(HttpSecurity http)
方法如下所示:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().ignoringAntMatchers("/h2-console").disable()
.authorizeRequests()
.antMatchers("/webjars/**", "/static/**", "/images/**", "/**/favicon.ico").permitAll()
.antMatchers("/heat/**", "/power/**", "/water/**").permitAll()
// start allowing h2-console
.antMatchers("/h2-console/**").permitAll();
http.csrf().disable();
http.headers().frameOptions().disable()
// end allowing h2-console
.and().authorizeRequests().antMatchers("/info").permitAll()
.and().authorizeRequests().antMatchers("/users/**").authenticated()
.and().authorizeRequests().antMatchers("/users/**").hasAnyAuthority("ADMIN", "SUPERUSER")
.and().formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.deleteCookies("remove")
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.invalidateHttpSession(true)
.and().exceptionHandling().accessDeniedPage("/access_denied");
}
来自IndexController
的映射非常简单,它只返回登录
模板:
@RequestMapping("/login")
public String loginForm() {
return "login";
}
要尝试的事情:
1)用@EnableWebMvc
注释您的配置。
2) 将ROLE_ADMIN
替换为justADMIN
(以及其他相应的角色)。
3) 在控制器中,打印以下内容以查看当前角色:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Set<String> roles = authentication.getAuthorities().stream()
.map(r -> r.getAuthority()).collect(Collectors.toSet());
System.out.println(roles);
如果这对您不起作用,可以尝试HttpServletRequest
中的getUserPrincipal()
。
除此之外:
我加入了我的MVC配置,以便您可以尝试最新的Thymeleaf和Spring Security版本。这里有一些额外的配置,所以你可以删除与你的项目无关的内容。
@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configuration) {
configuration.enable();
}
@Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setOrder(1);
resolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
resolver.setTemplateEngine(templateEngine());
return resolver;
}
@Bean
public TemplateEngine templateEngine() {
Set<ITemplateResolver> templateResolvers = new LinkedHashSet<>(1);
templateResolvers.add(webTemplateResolver());
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolvers(templateResolvers);
Set<IDialect> dialects = new LinkedHashSet<>(2);
dialects.add(new SpringSecurityDialect());
dialects.add(new Java8TimeDialect());
templateEngine.setAdditionalDialects(dialects);
return templateEngine;
}
@Bean
public ITemplateResolver webTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("/WEB-INF/thymeleaf/");
resolver.setTemplateMode(TemplateMode.HTML);
resolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
resolver.setSuffix(".html");
resolver.setCacheable(false);
resolver.setOrder(2);
return resolver;
}
@Bean
public ViewResolver tilesViewResolver() {
UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
viewResolver.setViewClass(TilesView.class);
viewResolver.setOrder(0);
return viewResolver;
}
@Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions("/WEB-INF/**/views.xml");
return configurer;
}
@Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/403");
registry.addViewController("/404");
registry.addViewController("/about");
//edited for brevity
}
@Bean
public ReloadableResourceBundleMessageSource messageSource() {
ReloadableResourceBundleMessageSource source = new ReloadableResourceBundleMessageSource();
source.setBasename("classpath:messages");
source.setDefaultEncoding(StandardCharsets.UTF_8.name());
return source;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
registry.addInterceptor(themeChangeInterceptor());
registry.addInterceptor(deviceResolverHandlerInterceptor());
super.addInterceptors(registry);
}
@Bean
public HandlerInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("lang");
return interceptor;
}
@Bean
public HandlerInterceptor themeChangeInterceptor() {
ThemeChangeInterceptor interceptor = new ThemeChangeInterceptor();
interceptor.setParamName("theme");
return interceptor;
}
@Bean
public ResourceBundleThemeSource themeSource() {
ResourceBundleThemeSource themeSource = new ResourceBundleThemeSource();
themeSource.setBasenamePrefix("theme-");
return themeSource;
}
@Bean
public PersistedThemeResolver themeResolver() {
PersistedThemeResolver resolver = new PersistedThemeResolver();
resolver.setDefaultThemeName("default");
return resolver;
}
@Bean
public HandlerInterceptor deviceResolverHandlerInterceptor() {
return new DeviceResolverHandlerInterceptor();
}
@Bean
public CookieLocaleResolver localeResolver() {
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setDefaultLocale(Locale.US);
return resolver;
}
//removed custom bean declaration
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new ServletWebArgumentResolverAdapter(new DeviceWebArgumentResolver()));
super.addArgumentResolvers(argumentResolvers);
}
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(100);
executor.initialize();
return executor;
}
}
工作pom摘录:
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>
在多次尝试不同的配置后,我找到了一个解决方法。在这种情况下,sec:authorize=“hasAuthority('ADMIN')”
属性起作用:
<div class="row" sec:authorize="hasRole('ROLE_ADMIN')">
<div class="col-md-10 col-md-offset-2">
<h2>User Has Role Admin</h2>
</div>
</div>
<div class="row" sec:authorize="hasAuthority('ADMIN')">
<div class="col-md-10 col-md-offset-2">
<h2>User Has Authority Admin</h2>
</div>
</div>
和用户有权限管理员
头呈现在页面上。
仍然不知道为什么sec:authorize=“hasRole('ROLE_ADMIN')”
属性不起作用,正如thymeleaf extras springsecurity
GitHub页面上的一个示例所示:https://github.com/thymeleaf/thymeleaf-extras-springsecurity#using-属性
希望这能帮助一些人,尽管问题仍然悬而未决。
解决此任务的另一种方法是使用此语法检查角色:
<div class="row" th:if="${#request.isUserInRole('SUPERUSER')}">
<h2>This will only be displayed if authenticated user has role ROLE_SUPERUSER.</h2>
</div>
它不使用sec
命名空间,实际上完全不需要thymeleaf-exatas-springsecurity4依赖项来使用它。
我正在尝试使用Spring Boot、Spring Security4、Thymeleaf,如果用户有角色“admin”或其他任何东西,html块应该会显示出来,但现在它总是显示在页面上。这是我的html 这里是我的pom.xml,我添加了thymeleaf-extras-springsecurity4。还尝试了thymeleaf-extras-springsecurity3 这是我的securi
默认情况下,SEC:authorize-URL标记不适用于Spring boot security: 添加依赖项 我是不是漏掉了什么?这是预期的行为吗?我需要定义什么才能使authorize-url像使用XML配置安全性时那样工作? 此问题与SpringBootWebSecurityConfiguration中的基本身份验证及其自动配置有关: 在SampleMethodSecurityApplic
我的配置在这里 和 错误消息是:org.thymeleaf.templateparser.text.TextParseException:评估SpringEL表达式的异常:"book.price"(模板:"[#th: each="book:${book}"] - [(${ book.price})][/]"......原因:org.springframework.expression.spel.S
我正在使用带Spring security的Thymeleaf模板引擎。为了使用sec:authorize功能,我还使用了Thymeleaf-Spring Security集成模块,但由于某些原因,它不起作用。我没有收到任何错误,但是html div块中的所有代码都会被执行,无论用户扮演哪个角色。 例如,当我以员工身份登录时,我也会看到“去领导”和“去系统”按钮,但我不想让员工看到这些按钮。 这是
我有以下Spring Security配置: 我想让每个人(包括经过身份验证的用户和未经身份验证的用户)都可以访问特定的页面(比如索引页面(“/”),但同时,能够根据用户是否经过身份验证以及其角色来管理应该在jsp中看到哪些部分。 我的jsp部分如下所示: 所有的认证机制都可以正常工作。问题是,即使我使用“管理员”角色登录,链接也永远不会显示。 我尝试调试我的userdetails服务实现,并验证
我发现了许多类似的问题,但没有一个解决了我的问题。我的问题是可以访问的函数 下面是我的spring-security.xml代码。