Spring Security(一)自定义表单及认证授权

1、默认表单认证

  创建 springboot 项目,依赖:

<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>

  写一个测试 controller

@RestController
@RequestMapping("/index")
public class IndexController {

    @RequestMapping("/test1")
    public String test1(String name, Integer age) {
        return "test1";
    }

}

  启动项目,访问 http://localhost:8089/BootDemo/index/test1,弹出默认表单认证

   默认用户名为 user, 密码是动态生成并打印到控制台的一窜随机码。当然,用户名和密码可以在application.properties 中配置

spring.security.user.name=test
spring.security.user.password=123

2、自定义表单登陆页

  虽然spring security 自带的表单登陆页可以方便快速地启动,但大多数应用程序更希望提供自己的的表单登陆页,此时就需要自定义表单登陆页。

   WebSecurityConfig

package com.oy;

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;

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated()
            .and().formLogin().loginPage("/mylogin.html")
            .loginProcessingUrl("/login") // 指定处理登陆请求的路径
            .permitAll() // 登陆页和 "/login" 不设置权限
            .and().csrf().disable();
    }
}

  表单登陆页

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>自定义表单登陆页</h2>
<form action="login" method="post">
用户名:<input type="text" name="username" /><br/>&nbsp;&nbsp;&nbsp;码:<input type="text" name="password" /><br/>
<input type="submit" value="提交" />
</form>
</body>
</html>
View Code

  启动项目,访问 localhost:8089/BootDemo/index/test1,自动跳转到登陆页(浏览器地址为 http://localhost:8089/BootDemo/mylogin.html)。

  输入test/123, 登陆成功,拿到响应结果:

   如果输入错误的用户名或密码,响应结果(状态码 302,重定向到登陆页)

   对应现在前后端分离的项目而言,重定向不在需要后端做,后端一般返回 json 数据,告知前端登陆成功与否,由前端决定如何处理后续逻辑,而非由服务器主动执行页面跳转。这在 Spring Security 中同样可以实现。

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and()
            .formLogin().loginPage("/mylogin.html")
            .loginProcessingUrl("/login") // 指定处理登陆请求的路径
            // 指定登陆成功时的处理逻辑
            .successHandler(new AuthenticationSuccessHandler() {

                @Override
                public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                        Authentication authentication) throws IOException, ServletException {
                    response.setContentType("application/json;charset=utf-8");
                    response.getWriter().write("{\"code\":0, \"data\":{}}");
                }
                
            })
            // 指定登陆失败时的处理逻辑
            .failureHandler(new AuthenticationFailureHandler() {

                @Override
                public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                        AuthenticationException exception) throws IOException, ServletException {
                    response.setContentType("application/json;charset=utf-8");
                    response.setStatus(401);
                    response.getWriter().write("{\"code\":0, \"msg\":\"用户名或密码错误\"}");
                }
                
            })
            
            .permitAll().and()
            .csrf().disable();
    }
}

  其中,successHandler()方法带有一个 Authentication 参数,携带当前登陆用户名及其角色等信息;而 failureHandler() 方法携带一个AuthenticationException 异常参数。

3、自定义数据库模型的认证和授权

  前面沿用了 Spring Security 默认的安全机制:仅有一个用户,仅有一种角色。在实际开发中,这自然是无法满足要求的。

  编写三个 controller 进行测试,其中 /admin/api 下的内容是系统后台管理相关的API,必须拥有管理员权限(具有 "admin" 角色)才能访问; /user/api 必须在用户登陆并且具有 “user” 角色才能访问。

@RestController
@RequestMapping("/admin/api")
public class AdminController {
    @GetMapping("/hello")
    public String hello() {
        return "hello, admin";
    }
}
@RestController
@RequestMapping("/user/api")
public class UserController {
    @GetMapping("/hello")
    public String hello() {
        return "hello, user";
    }
}
@RestController
@RequestMapping("/app/api")
public class AppController {
    @GetMapping("/hello")
    public String hello() {
        return "hello, app";
    }
}
View Code

  启动项目,访问 http://localhost:8089/BootDemo/user/api/hello,跳转到登陆页面,使用 test/123 登陆后。再次访问 http://localhost:8089/BootDemo/user/api/hello,此时服务器返回 403,表示用户授权失败(401 代表用户认证失败)。

  自定义数据库模型

  

---

猜你喜欢

转载自www.cnblogs.com/xy-ouyang/p/12695264.html