采用注解方式实现security
采用注解方式使用security,首先我们需要用注解方式实现Spring MVC,新建一个Maven项目
本项目目录结构如下:
我们会发现在WEB-INF中没有web.xml文件,下面会介绍,采用java Config方式进行了配置
一、在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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.petter</groupId> <artifactId>hello-world-annotation</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>hello-world-annotation Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring.version>4.3.5.RELEASE</spring.version> <spring.security.version>4.2.1.RELEASE</spring.security.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring4</artifactId> <version>3.0.2.RELEASE</version> </dependency> <!-- Spring Security --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>${spring.security.version}</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>${spring.security.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf8</encoding> </configuration> </plugin> </plugins> </build> </project>
二、配置SpringMVC项目
1、编写AppConfig类文件,其相当于spring的xml配置文件,代码如下:
package com.petter.config; 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.thymeleaf.spring4.SpringTemplateEngine; import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.spring4.view.ThymeleafViewResolver; /** * 相当于spring的xml配置文件 * @author hongxf * @since 2017-03-08 10:11 */ @EnableWebMvc @Configuration @ComponentScan({"com.petter.*"}) public class AppConfig { @Bean public SpringResourceTemplateResolver springResourceTemplateResolver() { SpringResourceTemplateResolver springResourceTemplateResolver = new SpringResourceTemplateResolver(); springResourceTemplateResolver.setPrefix("/WEB-INF/pages/"); springResourceTemplateResolver.setSuffix(".html"); springResourceTemplateResolver.setTemplateMode("HTML"); springResourceTemplateResolver.setCacheable(false); springResourceTemplateResolver.setCharacterEncoding("UTF-8"); return springResourceTemplateResolver; } @Bean public SpringTemplateEngine springTemplateEngine() { SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine(); springTemplateEngine.setTemplateResolver(springResourceTemplateResolver()); return springTemplateEngine; } @Bean public ThymeleafViewResolver thymeleafViewResolver() { ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver(); thymeleafViewResolver.setTemplateEngine(springTemplateEngine()); thymeleafViewResolver.setCharacterEncoding("UTF-8"); return thymeleafViewResolver; } }
2、编写SpringMVCInitiallizer类文件,继承AbstractAnnotationConfigDispatcherServletInitializer,其相当于没有了的web.xml文件,代码如下:
package com.petter; import com.petter.config.AppConfig; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; /** * 相当于web.xml文件 * @author hongxf * @since 2017-03-08 10:17 */ public class SpringMVCInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { /** * 应用程序上下文配置文件,可以是多个,即相当于多个xml文件配置 * @return */ @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[]{AppConfig.class}; } /** * 获取应用程序上下文配置文件 * 如果所有配置已经在AppConfig中配置,则可以设为null * @return */ @Override protected Class<?>[] getServletConfigClasses() { return null; } /** * 指定拦截路径 * @return */ @Override protected String[] getServletMappings() { return new String[]{"/"}; } }
3、编写admin.html和hello.html文件,内容一致
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>admin</title> </head> <body> <h1 th:text="|标题: ${title}|">Title : XXX</h1> <h1 th:text="|信息: ${message}|">Message : XXX</h1> </body> </html>
4、编写HelloController
package com.petter.web; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; /** * @author hongxf * @since 2017-03-08 9:29 */ @Controller public class HelloController { @RequestMapping(value = { "/", "/welcome" }, method = RequestMethod.GET) public ModelAndView welcomePage() { ModelAndView model = new ModelAndView(); model.addObject("title", "Spring Security Hello World"); model.addObject("message", "This is welcome page!"); model.setViewName("hello"); return model; } @RequestMapping(value = "/admin", method = RequestMethod.GET) public ModelAndView adminPage() { ModelAndView model = new ModelAndView(); model.addObject("title", "Spring Security Hello World"); model.addObject("message", "This is protected page - Admin Page!"); model.setViewName("admin"); return model; } @RequestMapping(value = "/dba", method = RequestMethod.GET) public ModelAndView dbaPage() { ModelAndView model = new ModelAndView(); model.addObject("title", "Spring Security Hello World"); model.addObject("message", "This is protected page - Database Page!"); model.setViewName("admin"); return model; } }
启动程序,访问http://localhost:8080/admin 结果如下:
三、添加security配置
1、继承AbstractSecurityWebApplicationInitializer类编写类文件SpringSecurityInitializer,代码如下:
package com.petter.config; import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; /** * 相当于在web.xml中配置spring security的filter * @author hongxf * @since 2017-03-08 10:10 */ public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer { //do nothing }
相当于在web.xml文件中配置的filter,即
<filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2、配置security的过滤配置,编写文件SecurityConfig,代码如下:
package com.petter.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.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; /** * 相当于spring-security.xml中的配置 * @author hongxf * @since 2017-03-08 9:30 */ @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { /** * 在内存中设置三个用户 * @param auth * @throws Exception */ @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("hongxf").password("123456").roles("USER"); auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN"); auth.inMemoryAuthentication().withUser("dba").password("123456").roles("DBA"); } /** * 配置权限要求 * @param http * @throws Exception */ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") .antMatchers("/dba/**").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')") .and().formLogin(); } }
相当于xml配置文件如下所示:
<http auto-config="true"> <intercept-url pattern="/admin**" access="hasRole('ROLE_ADMIN')" /> <intercept-url pattern="/dba**" access="hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')" /> </http> <authentication-manager> <authentication-provider> <user-service> <user name="hongxf" password="123456" authorities="ROLE_USER" /> <user name="admin" password="123456" authorities="ROLE_ADMIN" /> <user name="dba" password="123456" authorities="ROLE_DBA" /> </user-service> </authentication-provider> </authentication-manager>
启动程序,访问http://localhost:8080/dba 会跳转到默认登录页:
登录以后,因为dba页面拥有ADMIN权限可以进入,所以成功跳转到页面