Spring Security Method Level Annotations Example

摘要: This tutorial demonstrates how to use Spring Security Method Level Annotations. We can use Spring Security to secure our service layer. We can restrict which roles are able to execute a method by annotating the method with any of spring security annotations or the standard java JSR-250 annotaitons.

This tutorial demonstrates how to use Spring Security Method Level Annotations. We can use Spring Security to secure our service layer. We can restrict which roles are able to execute a method by annotating the method with any of spring security annotations or the standard java JSR-250 annotaitons.

Maven Dependencies

We use Apache Maven to manage our project dependencies. Make sure the following dependencies reside on the class-path.

<?xml version="1.0" encoding="UTF-8"?>
<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>
    <groupId>com.memorynotfound.spring.security</groupId>
    <artifactId>method-level-security</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <url>http://memorynotfound.com</url>
    <name>Spring Security - ${project.artifactId}</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>jsr250-api</artifactId>
            <version>1.0</version>
        </dependency>


        <!-- testing -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Enable Method Level Security

By annotating the class with @EnableGlobalMethodSecurity, we can enable method level security using annotations. We can optionally configure which annotations we’ll allow. You can enable one of the following.

  • securedEnabled – enables the spring @Secured annotation.
  • jsr250Enabled – enables the JSR-250 standard java security annotations.
  • prePostEnabled – enables the spring @PreAuthorize and PostAuthorize annotations.
package com.memorynotfound.spring.security.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableGlobalMethodSecurity(
        securedEnabled = true,
        jsr250Enabled = true,
        prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic();
    }

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

}

The equivalent Spring Security XML Configuration spring-security-config.xml is located in the src/main/resources folder.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:beans="http://www.springframework.org/schema/beans"
             xsi:schemaLocation="http://www.springframework.org/schema/security
                                 http://www.springframework.org/schema/security/spring-security.xsd
                                 http://www.springframework.org/schema/beans
                                 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <global-method-security
            secured-annotations="enabled"
            jsr250-annotations="enabled"
            pre-post-annotations="enabled"/>
    
    <http>
        <http-basic/>
    </http>

    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="user"
                      password="password"
                      authorities="ROLE_USER" />
                <user name="manager"
                      password="password"
                      authorities="ROLE_MANAGER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>

</beans:beans>

Spring Security Secured Annotations

Adding an annotation to a method (on a class or interface) limits the access to that method accordingly. Here we used the @Secured annotation.

package com.memorynotfound.spring.security.web;

import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("book")
public class BookController {

    @GetMapping("anonymous")
    @Secured("ROLE_ANONYMOUS")
    public String anonymously() {
        return "Hello, World!";
    }

    @GetMapping("has-role")
    @Secured("ROLE_ADMIN")
    public String hasRole() {
        return "Hello, World!";
    }

}

Spring Security JSR-250 Annotations

Adding an annotation to a method (on a class or interface) limits the access to that method accordingly. Here we used the @PermitAll and @RolesAllowed annotations.

package com.memorynotfound.spring.security.web;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("anonymous")
    @PermitAll
    public String anonymously() {
        return "Hello, World!";
    }

    @GetMapping("has-role")
    @RolesAllowed({"ROLE_ADMIN"})
    public String hasRole() {
        return "Hello, World!";
    }

}

Spring Security Pre Post Annotations

Adding an annotation to a method (on a class or interface) limits the access to that method accordingly. Here we used the @PreAuthorize annotation.

package com.memorynotfound.spring.security.web;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("bank")
public class BankController {

    @GetMapping("anonymous")
    @PreAuthorize("permitAll()")
    public String anonymously() {
        return "Hello, World!";
    }

    @GetMapping("has-role")
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')")
    public String hasRole() {
        return "Hello, World!";
    }

}

Demo

Access http://localhost:8080/bank/has-role with user: user.

Access http://localhost:8080/bank/anonymous with user: user.

Spring Security Method Level Annotations Integration Test

We can use MockMvc to write some spring integration tests.

package com.memorynotfound.spring.security.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
@RunWith(SpringJUnit4ClassRunner.class)
public class BasicAuthenticationIntegrationTests {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void accessAnonymous() throws Exception {
        this.mockMvc.perform(
                get("/bank/anonymous")
                        .with(httpBasic("user", "password")))
                .andExpect(
                        status().isOk());
    }

    @Test
    public void accessRoleProtected() throws Exception {
        this.mockMvc.perform(
                get("/bank/has-role")
                        .with(httpBasic("user", "password")))
                .andExpect(
                        status().is4xxClientError());
    }

}

Spring Security Integration Test Results

Download

上一篇: Spring Boot + Spring Security + Hibernate Configuration Example
下一篇: Spring Security Basic Authentication Configuration Example
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号