Spring Security方法级别的控制

除了认证(authentication),Spring Security还检查已登录用户的授权(authorization)。在登录后,基于用户的角色来确定哪些用户有权访问特定资源。

在创建用户时,我们可以在WebSecurityConfig类中指定用户的角色。

方法级别的安全性会限制未授权的用户,只允许经过身份验证的用户访问。

下面是一个示例。首先,创建一个Maven项目并提供项目详细信息。

spring-security-at-method-level.png

创建Maven项目

首先创建一个Maven项目并提供项目详细信息。

初始时,项目如下所示:

spring-security-at-method-level2.png

Spring Security配置

配置项目以实现安全性。需要以下四个Java文件,将它们都放在cn.javatiku包中。

AppConfig.java

package cn.javatiku;  
import org.springframework.context.annotation.Bean;    
import org.springframework.context.annotation.ComponentScan;    
import org.springframework.context.annotation.Configuration;    
import org.springframework.web.servlet.config.annotation.EnableWebMvc;    
import org.springframework.web.servlet.view.InternalResourceViewResolver;    
import org.springframework.web.servlet.view.JstlView;    
@EnableWebMvc    
@Configuration    
@ComponentScan({ "cn.javatiku.controller.*" })    
public class AppConfig {    
    @Bean    
    public InternalResourceViewResolver viewResolver() {    
        InternalResourceViewResolver viewResolver    
                          = new InternalResourceViewResolver();    
        viewResolver.setViewClass(JstlView.class);    
        viewResolver.setPrefix("/WEB-INF/views/");    
        viewResolver.setSuffix(".jsp");    
        return viewResolver;    
    }    
}  

MvcWebApplicationInitializer.java

package cn.javatiku;  
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;    
public class MvcWebApplicationInitializer extends    
        AbstractAnnotationConfigDispatcherServletInitializer {    
    @Override    
    protected Class<?>[] getRootConfigClasses() {    
        return new Class[] { WebSecurityConfig.class };    
    }    
    @Override    
    protected Class<?>[] getServletConfigClasses() {    
        // TODO Auto-generated method stub    
        return null;    
    }    
    @Override    
    protected String[] getServletMappings() {    
        return new String[] { "/" };    
    }    
}  

SecurityWebApplicationInitializer.java

package cn.javatiku;  
import org.springframework.security.web.context.*;    
public class SecurityWebApplicationInitializer    
    extends AbstractSecurityWebApplicationInitializer {    
}    

WebSecurityConfig.java

package cn.javatiku;  
import org.springframework.context.annotation.*;  
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.*;    
import org.springframework.security.core.userdetails.*;  
import org.springframework.security.core.userdetails.User.UserBuilder;    
import org.springframework.security.provisioning.InMemoryUserDetailsManager;  
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;    
@EnableWebSecurity    
@ComponentScan("cn.javatiku")    
@EnableGlobalMethodSecurity(prePostEnabled=true)  
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {    
@Bean    
public UserDetailsService userDetailsService() {  
    // ensure the passwords are encoded properly  
     UserBuilder users = User.withDefaultPasswordEncoder();  
     InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();  
manager.createUser(users.username("irfan").password("user123").roles("USER").build());  
manager.createUser(users.username("admin").password("admin123").roles("ADMIN").build());  
     return manager;  
    }   
@Override    
protected void configure(HttpSecurity http) throws Exception {    
      http.authorizeRequests().  
      antMatchers("/index","/").permitAll()  
      .antMatchers("/admin","/user").authenticated()  
      .and()  
      .formLogin()  
      .and()  
      .logout()  
      .logoutRequestMatcher(new AntPathRequestMatcher("/logout"));  
}    
}    

控制器

cn.javatiku.controller包内创建一个名为HomeController的控制器。以下是控制器的代码。

HomeController.java

package cn.javatiku.controller;  
import org.springframework.security.access.prepost.PreAuthorize;  
import org.springframework.stereotype.Controller;    
import org.springframework.web.bind.annotation.RequestMapping;    
import org.springframework.web.bind.annotation.RequestMethod;  
import org.springframework.web.bind.annotation.ResponseBody;  
@Controller    
public class HomeController {    
    @RequestMapping(value="/", method=RequestMethod.GET)    
    public String index() {    
        return "index";    
    }    
    @RequestMapping(value="/user", method=RequestMethod.GET)    
    public String user() {    
       return "admin";  
    }    
    @RequestMapping(value="/admin", method=RequestMethod.GET)    
    public String admin() {    
        return "admin";    
    }  
    // Only, a person having ADMIN role can access this method.  
    @RequestMapping(value="/update", method=RequestMethod.GET)   
    @ResponseBody  
    @PreAuthorize("hasRole('ROLE_ADMIN')")  
    public String update() {    
        return "record updated ";    
    }  
}   

视图

创建视图(JSP页面)以向浏览器生成输出。

index.jsp

<html>    
<head>    
<title>Home Page</title>    
</head>    
<body>    
Welcome to javatiku! <br> <br>  
Login as:   
<a href="admin">Admin</a> <a href="user">User</a>  
</body>    
</html>   

admin.jsp

<html>    
<head>    
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">    
<title>Home Page</title>    
</head>    
<body>    
<span style="color: green">Login Successful!</span> ? <a href="logout" style="text-decoration: none;">logout</a>  <br> <br>  
<a href="update" style="text-decoration: none;">Update Record</a>  
</body>    
</html>   

项目依赖

以下是包含所有必需依赖项的pom.xml文件。

<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>cn.javatiku</groupId>  
  <artifactId>springmethod</artifactId>  
  <version>0.0.1-SNAPSHOT</version>  
  <packaging>war</packaging>  
  <properties>    
    <maven.compiler.target>1.8</maven.compiler.target>    
    <maven.compiler.source>1.8</maven.compiler.source>    
</properties>    
<dependencies>    
  <dependency>    
            <groupId>org.springframework</groupId>    
            <artifactId>spring-webmvc</artifactId>    
            <version>5.0.2.RELEASE</version>    
        </dependency>    
        <dependency>    
        <groupId>org.springframework.security</groupId>    
        <artifactId>spring-security-web</artifactId>    
        <version>5.0.0.RELEASE</version>    
    </dependency>    
<dependency>  
    <groupId>org.springframework.security</groupId>  
    <artifactId>spring-security-core</artifactId>  
    <version>5.0.4.RELEASE</version>  
</dependency>  
    <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->  
<dependency>  
    <groupId>org.springframework.security</groupId>  
    <artifactId>spring-security-config</artifactId>  
    <version>5.0.4.RELEASE</version>  
</dependency>  
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->  
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->    
<dependency>    
    <groupId>javax.servlet</groupId>    
    <artifactId>javax.servlet-api</artifactId>    
    <version>3.1.0</version>    
    <scope>provided</scope>    
</dependency>    
<dependency>    
    <groupId>javax.servlet</groupId>    
    <artifactId>jstl</artifactId>    
    <version>1.2</version>    
</dependency>    
<!-- https://mvnrepository.com/artifact/org.springframework/spring-framework-bom -->  
</dependencies>    
  <build>    
    <plugins>    
        <plugin>    
            <groupId>org.apache.maven.plugins</groupId>    
            <artifactId>maven-war-plugin</artifactId>    
            <version>2.6</version>  
                   <configuration>    
                <failOnMissingWebXml>false</failOnMissingWebXml>    
            </configuration>    
        </plugin>    
    </plugins>    
  </build>    
</project>  

项目结构

添加所有文件后,项目结构如下:

spring-security-at-method-level3.png

启动服务器

输出:

spring-security-at-method-level4.png

首先以管理员身份登录。

spring-security-at-method-level5.png

登录后,

spring-security-at-method-level6.png

单击update record,可以看到记录已更新,因为用户角色是ADMIN。
spring-security-at-method-level7.png

用户登录

现在,以用户身份登录。

spring-security-at-method-level8.png

spring-security-at-method-level9.png

登录后,单击update record,可以看到服务器拒绝访问,因为用户角色是USER。

spring-security-at-method-level10.png

标签: spring, Spring教程, Spring技术, Spring语言学习, Spring学习教程, Spring下载, Spring框架, Spring框架入门, Spring框架教程, Spring框架高级教程, Spring面试题, Spring笔试题, Spring编程思想