<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.0.5.RELEASE</version> <type>jar</type> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.0.5.RELEASE</version> <type>jar</type> </dependency> <!-- Add Spring Security --> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>3.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>3.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>3.2.4.RELEASE</version> </dependency> <!-- Add Jstl Dependencies --> <dependency> <groupId>org.apache.taglibs</groupId> <artifactId>taglibs-standard-jstlel</artifactId> <version>1.2.1</version> </dependency> </dependencies>
AppController.java
) package com.elennaro.sshwa.controllers; //Import section ommited... @Controller public class AppController { @RequestMapping(value = {"/", "/helloworld**"}, method = {RequestMethod.GET}) public ModelAndView welcomePage() { ModelAndView model = new ModelAndView(); model.addObject("title", "Spring Security Tutorial"); model.addObject("message", "Welcome Page !"); model.setViewName("helloworld"); return model; } @RequestMapping(value = "/protected**", method = RequestMethod.GET) public ModelAndView protectedPage() { ModelAndView model = new ModelAndView(); model.addObject("title", "Spring Security 3.2.4 Hello World Tutorial"); model.addObject("message", "This is protected page - Only for Admin Users!"); model.setViewName("protected"); return model; } @RequestMapping(value = "/confidential**", method = RequestMethod.GET) public ModelAndView adminPage() { ModelAndView model = new ModelAndView(); model.addObject("title", "Spring Security 3.2.4 Hello World Tutorial"); model.addObject("message", "This is confidential page - Need Super Admin Role!"); model.setViewName("protected"); return model; } }
ModelAndView
class). The name of the view component is also specified in the model. To bind the names of the components of the view (with your permission, I will call the components of the view generically views, from the English View) to specific display files (in our case, the JSP files), you need to register the class with the WebConfig.java
settings. The class description is presented below.@Configuration
(in the future we will call such classes configuration). package com.elennaro.sshwa.config.application; //Import section ommited... @Configuration @EnableWebMvc @ComponentScan({ "com.elennaro.sshwa.config", "com.elennaro.sshwa.controllers" }) //@Import({ AppSecurityConfig.class }) public class WebConfig { @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } }
@Configuration
annotation).@ComponentScan
annotation, @ComponentScan
specify the Spring framework that components should be searched inside the com.elennaro.sshwa.config
and com.elennaro.sshwa.controllers
. Here, experts advise: it is better to always indicate specific packages, and not all at once with the help of *
. That is, we could specify all the packages: com.elennaro.sshwa.*
And everything would work. But if we appeared elsewhere in the same @ComponentScan
we would at best re-scan all the packages twice, and at worst stumbled upon a couple of unpleasant errors .../WEB-INF/views/
@Import({ AppSecurityConfig.class }))
annotation @Import({ AppSecurityConfig.class }))
. This line is specially commented out in the code. I wanted to show that the class with security settings ( AppSecurityConfig.java
) checked (as you will see below) with the @Configuration
annotation will be automatically found and connected to the framework Spring application, because the path to the package containing the AppSecurityConfig class AppSecurityConfig
specified in the @ComponentScan
annotation. Thanks to this, Spring will find and connect the configuration class automatically.AppController.java
controller itself will also fall under the component scan, since the path to the package containing it is specified in @ComponentScan({ "com.elennaro.sshwa.config", "com.elennaro.sshwa.controllers" })
and annotation @Controller
is listed for this class. package com.elennaro.sshwa.config; //Import section ommited... @Configuration @EnableWebSecurity public class AppSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user").password("user").roles("USER"); auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN"); auth.inMemoryAuthentication().withUser("superadmin").password("superadmin").roles("SUPERADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/protected/**").access("hasRole('ROLE_ADMIN')") .antMatchers("/confidential/**").access("hasRole('ROLE_SUPERADMIN')") .and().formLogin().defaultSuccessUrl("/", false); } }
@Configuration
@EnableWebSecurity.
@EnableWebSecurity
in conjunction with the WebSecurityConfigurerAdapter
class, is working on providing authentication. By default, HTTP authentication and web-based authentication are built into and active in Spring Security.ROLE_
prefix, while specifying the access
test expressions in the access
method, in which we, using the spring expression language ( SPEL ) (in our case, checking the role of the user hasRole('ROLE_ ')
), we write the role with the prefix ROLE_
. Another little trick to authenticate: defaultSuccessUrl("/", false)
, setting the second parameter ( alwaysUse
) to false
tells Spring Security that if it is successful, you can redirect the user to the page from which he came to the authentication page.AbstractAnnotationConfigDispatcherServletInitializer
. package com.elennaro.sshwa.config; //Import section ommited... public class SecurityInit extends AbstractSecurityWebApplicationInitializer { }
<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> <dispatcher>ERROR</dispatcher> <dispatcher>REQUEST</dispatcher> </filter-mapping>
package com.elennaro.sshwa.config; //Import section ommited... public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{ @Override protected Class<?>[] getRootConfigClasses() { return new Class[] {WebConfig.class}; // We dont need any special servlet config yet. } @Override protected Class<?>[] getServletConfigClasses() { return null; } @Override protected String[] getServletMappings() { return new String[] {"/"}; } }
getRootConfigClasses
method so that we return the WebConfig.class
application settings class. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <base href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Hello World</title> </head> <body> <header> <h1>Title : ${title}</h1> </header> <section> <h1>Message : ${message}</h1> </section> <div>Get <a href="protected">protected</a> resource for admin.</div> <div>Get <a href="confidential">confidential</a> resource for superadmin.</div> <footer> <div>Updated by Alex Art from <a href="https://in2circle.com" target="_blank">in2circle.com</a></div> </footer> </body> </html>
<%@ page isELIgnored="false" %> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <base href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Protected page</title> </head> <body> <h1>Title : ${title}</h1> <h1>Message : ${message}</h1> <c:if test="${pageContext.request.userPrincipal.name != null}"> <h2>Welcome : ${pageContext.request.userPrincipal.name} <%--@elvariable id="_csrf" type="org.springframework.web.bind.MissingServletRequestParameterException"--%> <c:url var="logoutUrl" value="/logout" /> <form action="${logoutUrl}" id="logout" method="post"> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> <input type="submit" name="submit" value="Log Out"> </form> </c:if> </h2> <div>Get <a href="protected">protected</a> resource for admin.</div> <div>Get <a href="confidential">confidential</a> resource for superadmin.</div> <footer> <div>Updated by Alex Art from <a href="https://in2circle.com" target="_blank">in2circle.com</a></div> </footer> </body> </html>
logout
and that by default the type of logout of the request must be POST and the request of logout must contain csrf token.Source: https://habr.com/ru/post/226791/
All Articles