Spring Boot Security - Thymeleaf sec:授权不起作用

Posted

技术标签:

【中文标题】Spring Boot Security - Thymeleaf sec:授权不起作用【英文标题】:Spring Boot Security - Thymeleaf sec:authorize not working 【发布时间】:2018-06-03 21:16:40 【问题描述】:

我正在尝试使用 Spring Boot、Spring Security 4、Thymeleaf。如果用户具有“管理员”角色或其他角色。应该显示 html 块。但现在它总是显示在页面上。 这是我的html

<html lang="en" xmlns:th="http://www.thymeleaf.org"
  xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<div sec:authorize="hasRole('ROLE_GUEST')">
    <p class="bg-info">guest</p>
    </div>
    <div sec:authorize="hasRole('ROLE_ADMIN')">
        <p class="bg-info">you can see this if you have permission to acess role_admin</p>
    </div>

这是我的 pom.xml,我确实添加了 thymeleaf-extras-springsecurity4。还尝试了 thymeleaf-extras-springsecurity3

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.zhongdihang.resp</groupId>
        <artifactId>resp-parent</artifactId>
        <version>1.0.0</version>
        <relativePath>../resp-parent</relativePath>
    </parent>
    <artifactId>resp-serve</artifactId>
    <packaging>war</packaging>
    <name>Real estate sharing platform serve</name>
    <description>Real estate sharing platform serve</description>
    <dependencies>
        <!-- Compile -->
        <dependency>
            <groupId>com.zhongdihang.resp</groupId>
            <artifactId>resp</artifactId>
        </dependency>
        <dependency>
            <groupId>com.zhongdihang.resp</groupId>
            <artifactId>resp-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-jdbc</artifactId>
        </dependency>
        <!-- Optional -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- Runtime -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <scope>runtime</scope>
            <version>11.2.0.4</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>sqljdbc4</artifactId>
            <version>4.0</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!--mapper -->
        <dependency>
            <groupId>net.sf.dozer</groupId>
            <artifactId>dozer</artifactId>
            <version>5.4.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>jcl-over-slf4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--  
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>
        -->
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

这是我的安全配置

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private RoleService roleService;


    @Autowired
    private SecurityUserDetailsService userDetailsService;

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() 
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder);
        return provider;
    

    @Value("$" + ApplicationConstants.THIS_APP_CONFIG_PREFIX + ".security.debug:false")
    private boolean debug = false;

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception 
        auth.userDetailsService(userDetailsService);
        auth.authenticationProvider(daoAuthenticationProvider());
    

    private void configureExceptionHandling(ExceptionHandlingConfigurer<HttpSecurity> handler) 
        handler.authenticationEntryPoint(new SecurityAuthenticationEntryPoint());
    
    private void configureAuthorizeRequests(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) 
        //registry.accessDecisionManager(new SecurityAccessDecisionManager());      
        registry.antMatchers("/login/**","/auth/**","/api/open/person/**","/api/booking/**","/api/module/menu","/api/booking").permitAll();
        List<RoleEntity> list = roleService.findAll();
        for (RoleEntity roleEntity : list) 
            if(roleEntity.getModule()!=null) 
                registry.antMatchers(roleEntity.getModule().getPath()+"/**").hasAuthority(roleEntity.getNumber()).anyRequest().authenticated();
            
        
        registry.anyRequest().authenticated();
        //registry.anyRequest().hasAnyRole("ADMINISTRATOR");
    

    private void configureFilter(HttpSecurity http) throws Exception 
         //http.addFilterBefore(new SecurityAuthorizationFilter(sessionrepo),
         //UsernamePasswordAuthenticationFilter.class);
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.headers().frameOptions().disable();
        configureFilter(http);
        configureExceptionHandling(http.exceptionHandling());
        configureAuthorizeRequests(http.authorizeRequests());
        http.csrf().disable();
        http.formLogin()
            .loginPage("/login")
            .usernameParameter("username")
            .passwordParameter("password")
            .failureHandler(new SecurityAauthenticationFailureHandler())
            .successHandler(new SecurityAuthenticationSuccessHandler())
            .permitAll();
        http.logout()
            .logoutUrl("/logout")
            .logoutSuccessHandler(new SecurityLogoutSuccessHandler())
            .permitAll();
    

    @Override
    public void configure(WebSecurity web) throws Exception 
        web.debug(debug);
        web.ignoring().antMatchers(HttpMethod.OPTIONS);
        web.ignoring().antMatchers("/assets/**");
        web.ignoring().antMatchers("/**.ico");
        web.ignoring().antMatchers("/v2/api-docs");
    

有人可以帮助我吗? 非常感谢~

【问题讨论】:

.But now it always display on the pagelogin 页面吗? 这个元素是写在 index.html 上的。我可以看到这两条消息。但是用户没有任何角色。 我找不到configAuthentication(AuthenticationManagerBuilder auth) 方法。 jdbcAuthentication 是您可以接受的解决方案吗? @Autowired public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception auth.userDetailsS​​ervice(userDetailsS​​ervice); auth.authenticationProvider(daoAuthenticationProvider()); 这就是你要找的吗? 也许吧,但我想它应该被称为configAuthentication。但是,不幸的是,我没有与userDetailsService 合作。相反,我可以通过jdbcAuthentication 帮助您。会有帮助吗? 【参考方案1】:

我正在使用springboot 1.5.8.RELEASEthymeleaf 3.0.9.RELEASE,所以我需要使用最新的org.thymeleaf.extras.所以尝试添加

       <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity4</artifactId>
            <version>3.0.2.RELEASE</version>
        </dependency>

在你的pom中。

【讨论】:

【参考方案2】:

您在这里缺少的是 HTML 中的标签

xmlns:sec="http://www.thymeleaf.org/extras/spring-security"

如果您使用的是 Springboot,则无论如何都不需要xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4" 标签。

【讨论】:

以上是关于Spring Boot Security - Thymeleaf sec:授权不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring Security 管理 Spring Boot 中的会话?

微服务和 Spring Security OAuth2

Spring Security with Boot

Spring Boot整合Thymeleaf

spring boot Security 简单使用

Spring Boot Security