spring security 入门
spring security使用入门
1. pom.xml
<?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>groupId</groupId> <artifactId>javabegin</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.58</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> </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>
2.配置文件
package com.example.javabegin; import com.example.javabegin.filter.VerficationCodeFilter; 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; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //super.configure(http); http.authorizeRequests() .antMatchers("/admin/api/**").hasRole("ADMIN") .antMatchers("/user/api/**").hasRole("USER") .antMatchers("/app/api/**", "/captcha.jpg").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/mylogin.html") //自定义登录页 .loginProcessingUrl("/auth/form") //自定义登录请求处理地址 .successHandler(new AuthenticationSuccessHandler() { @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { httpServletResponse.setContentType("application/json;charset=UTF-8"); httpServletResponse.setStatus(200); PrintWriter out = httpServletResponse.getWriter(); out.write("{\"error_code\":\"0\",\"message\":\"欢迎登录系统\"}"); } }) .failureHandler(new AuthenticationFailureHandler() { @Override public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { httpServletResponse.setContentType("application/json;charset=UTF-8"); httpServletResponse.setStatus(401); PrintWriter out = httpServletResponse.getWriter(); out.write("{\"error_code\":\"401\",\"name\":\"" + e.getClass() + "\",\"message\":\"" + e.getMessage() + "\"}"); } }) .permitAll() .and() .csrf().disable(); http.addFilterBefore(new VerficationCodeFilter(), UsernamePasswordAuthenticationFilter.class); } // @Override // protected void configure(AuthenticationManagerBuilder auth) throws Exception { // super.configure(auth); // } // // @Override // public void configure(WebSecurity web) throws Exception { // super.configure(web); // } }
3.启动文件
package com.example.javabegin; import com.google.code.kaptcha.util.Config; import com.google.code.kaptcha.Producer; import com.google.code.kaptcha.impl.DefaultKaptcha; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Properties; @RestController @SpringBootApplication public class App { @GetMapping("/hello") public String hello(){ return "hello world"; } /** * 添加两个用户 * @return */ @Bean public UserDetailsService userDetailsService(){ InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); manager.createUser(User.withUsername("user").password("123").roles("USER").build()); manager.createUser(User.withUsername("admin").password("123").roles("USER","ADMIN").build()); return manager; } //注入生成验证码类 @Bean public Producer captcha(){ Properties properties = new Properties(); properties.setProperty("kaptcha.image.width","150"); properties.setProperty("kaptcha.image.height","50"); properties.setProperty("kaptcha.textproducer.char.string","0123456789"); properties.setProperty("kaptcha.textproducer.char.length","4"); Config config = new Config(properties); DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); defaultKaptcha.setConfig(config); return defaultKaptcha; } public static void main(String[] args) { SpringApplication.run(App.class); } }
3.接口相关类
@RestController @RequestMapping("/admin/api") public class AdminController { @GetMapping("/hello") public String hello() { return "hello ,admin"; } } @RestController @RequestMapping("/app/api") public class AppController { @GetMapping("/hello") public String hello() { return "hello ,app"; } } @RestController @RequestMapping("/user/api") public class UserController { @GetMapping("/hello") public String hello() { return "hello ,user"; } }
4.生成验证吗
package com.example.javabegin.controller; import com.google.code.kaptcha.Producer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import javax.imageio.ImageIO; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.IOException; /** * 生成验证码 */ @Controller public class CaptchaController { @Autowired private Producer captchaProducer; @GetMapping("/captcha.jpg") public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("image/jpeg"); String capText = captchaProducer.createText(); request.getSession().setAttribute("captcha",capText); BufferedImage bi = captchaProducer.createImage(capText); ServletOutputStream out = response.getOutputStream(); ImageIO.write(bi ,"jpg",out); out.flush(); } }
package com.example.javabegin.filter; import org.springframework.util.StringUtils; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; public class VerficationCodeFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { //非登录请求不校验验证码 if (!"/auth/form".equals(httpServletRequest.getRequestURI())) { filterChain.doFilter(httpServletRequest, httpServletResponse); } else { try { verificationCode(httpServletRequest); filterChain.doFilter(httpServletRequest, httpServletResponse); } catch (Exception e) { //验证码错误处理 httpServletResponse.setContentType("application/json;charset=UTF-8"); httpServletResponse.setStatus(401); PrintWriter out = httpServletResponse.getWriter(); out.write("{\"error_code\":\"401\",\"name\":\"" + e.getClass() + "\",\"message\":\"" + e.getMessage() + "\"}"); } } } public void verificationCode(HttpServletRequest httpServletRequest) throws Exception { String requestCode = httpServletRequest.getParameter("captcha"); HttpSession session = httpServletRequest.getSession(); String savedCode = (String) session.getAttribute("captcha"); if (!StringUtils.isEmpty(savedCode)) { session.removeAttribute("captcha"); } if (StringUtils.isEmpty(requestCode) || StringUtils.isEmpty(savedCode) || !requestCode.equals(savedCode)) { throw new VerficationCodeException(); } } }
import org.springframework.security.core.AuthenticationException; public class VerficationCodeException extends AuthenticationException { public VerficationCodeException() { super("图形验证码校验失败"); } }
5.自定义登录页
<html> <head> <title>demo</title> <style type="text/css"> .login input {display:block;} </style> </head> <body> <div class="login"> <div class="login-top"> <h1>LOGIN FORM</h1> <form action="./auth/form" method="post"> <input type="text" name ="username" placeholder="username"/> <input type="password" name="password" placeholder="password"/> <div style="display:flex"> <input type="text" name="captcha" placeholder="captcha"/> <img src="/captcha.jpg" alt="captcha" height="50px" width="150px"> </div> <div class="forget"> <a href="#">forget password</a> <input type="submit" value="login"/> </div> </form> </div> <div class="login-bottom"> <h1>New User <a href="#">Register</a> Here</h1> </div> </div> </body> </html>