【Spring Security + OAuth2】前后端分离

Spring Security + OAuth2

第一章 Spring Security 快速入门
第二章 Spring Security 自定义配置
第三章 Spring Security 前后端分离配置
第四章 Spring Security 身份认证
第五章 Spring Security 授权
第六章 OAuth2


1、用户认证流程

登录成功后调用AuthenticationSuccessHandler
登录失败后调用AuthenticationFailureHandler
在这里插入图片描述
前后端分离时,前端发送请求给后端,后端需要返回一个json数据给前端。springSecurity是如何做到的呢?

  1. SpringSecurity 通过UsernamePasswordAuthenticationFilter获取前端输入的用户名和密码
  2. 根据用户名和密码生成UsernamePasswordAuthenticationToken
  3. AuthenticationManager会判断Token是否正确,根据结果发给相应的handler
  4. 此时handler返回json数据给前端。

2、引入fastjson

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
</dependency>

3、认证成功的响应

3.1、成功结果处理

public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

        Object principal = authentication.getPrincipal(); //获取用户身份信息
        //获取用户凭证信息。
        //Object credentials = authentication.getCredentials();
        //获取用户权限信息。
        //Collection<? extends GrantedAuthority> authenticationAuthorities = authentication.getAuthorities();
        HashMap result = new HashMap<>();
        result.put("code",0);
        result.put("messsage","登录成功");
        result.put("data",principal);

        //将结果对象转换成json字符串。
        String json = JSON.toJSONString(result);
        //返回json数据到前端。
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
    }
}

3.2、配置MyAuthenticationSuccessHandler

@Configuration //配置类
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        // authorizeHttpRequests() 开启授权保护
        // anyRequest() 对所以请求开启授权保护
        // authenticated()已认证请求会自动授权。
        http.authorizeHttpRequests(
                authorize -> authorize
                 //对所有请求就随时
                .anyRequest()
                .authenticated()
        );
        http.formLogin(form -> {
            form
                    .loginPage("/login")
                    .permitAll() //无需授权即可访问。
                    .usernameParameter("myName")//配置自定义的表单用户名参数
                    .passwordParameter("myPassword")//配置自定义的表单密码参数
                    .failureUrl("/login?failure")
                    .successHandler(new MyAuthenticationSuccessHandler())//认证成功时的处理。
            ;
        });
        //关闭csrf攻击防御
        http.csrf(csrf->csrf.disable());
        return http.build();
    }
}

4、认证失败响应

4.1、失败结果处理

public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {

        String msg = exception.getLocalizedMessage();
        HashMap result = new HashMap<>();
        result.put("code",-1);//失败
        result.put("messsage",msg);

        //将结果对象转换成json字符串。
        String json = JSON.toJSONString(result);
        //返回json数据到前端。
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
    }
}

4.2、配置MyAuthenticationFailureHandler

@Configuration //配置类
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        // authorizeHttpRequests() 开启授权保护
        // anyRequest() 对所以请求开启授权保护
        // authenticated()已认证请求会自动授权。
        http.authorizeHttpRequests(
                authorize -> authorize
                 //对所有请求就随时
                .anyRequest()
                .authenticated()
        );
        http.formLogin(form -> {
            form
                    .loginPage("/login")
                    .permitAll() //无需授权即可访问。
                    .usernameParameter("myName")//配置自定义的表单用户名参数
                    .passwordParameter("myPassword")//配置自定义的表单密码参数
                    .failureUrl("/login?failure")
                    .successHandler(new MyAuthenticationSuccessHandler())//认证成功时的处理。
                    .failureHandler(new MyAuthenticationFailureHandler())//认证失败时的处理。
            ;
        });//表单授权方式
        //    .httpBasic(withDefaults());//基本授权方式

        //关闭csrf攻击防御
        http.csrf(csrf->csrf.disable());
        return http.build();
    }
}

5、注销响应

5.1、注销结果处理

public class MyLogoutSuccessHandler implements LogoutSuccessHandler {
    @Override
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

        HashMap result = new HashMap<>();
        result.put("code",0);//失败
        result.put("messsage","注销成功");

        //将结果对象转换成json字符串。
        String json = JSON.toJSONString(result);
        //返回json数据到前端。
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
    }
}

5.2、SecurityFilterChain 配置

在WebSecurityConfig,加入注销配置。

   @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        // authorizeHttpRequests() 开启授权保护
        // anyRequest() 对所以请求开启授权保护
        // authenticated()已认证请求会自动授权。
        http.authorizeHttpRequests(
                authorize -> authorize
                 //对所有请求就随时
                .anyRequest()
                .authenticated()
        );
        http.formLogin(form -> {
            form
                    .loginPage("/login")
                    .permitAll() //无需授权即可访问。
                    .usernameParameter("myName")//配置自定义的表单用户名参数
                    .passwordParameter("myPassword")//配置自定义的表单密码参数
                    .failureUrl("/login?failure")
                    .successHandler(new MyAuthenticationSuccessHandler())//认证成功时的处理。
                    .failureHandler(new MyAuthenticationFailureHandler())//认证失败时的处理。
            ;
        });//表单授权方式
        //    .httpBasic(withDefaults());//基本授权方式

        //注销配置
        http.logout(logout->{
            logout.logoutSuccessHandler(new MyLogoutSuccessHandler());//注销成功时的处理
        });
        //关闭csrf攻击防御
        http.csrf(csrf->csrf.disable());
        return http.build();
    }

6、请求未认证的接口

6.1、实现AuthenticationEntryPoint接口

Servlert Authentication Architecture :: Spring Security
当访问一个需要认证之后才能访问的接口的时候,Spring Security会使用 AuthenticationEntryPoint 将用户请求跳转到登录页面,要求用户提供登录凭证。
这里我们也希望系统返回json结果,因此我们定义类实现AuthenticationEntryPoint接口

package com.security.demo.config;
import ...

public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint{

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {

        String localizeMessage = "需要登录";
        HashMap result = new HashMap();
        result.put("code",-1);
        result.put("message",localizeMessage);

        //将结果对象转换成json字符串
        String json = JSON.toJSONString(result);

        //返回json数据到前端
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
    }
}

6.2、配置MyAuthenticationFailureHandler

//注销配置
http.logout(logout->{
	logout.logoutSuccessHandler(new MyLogoutSuccessHandler());//注销成功时的处理
});

7、跨域

跨域全称是跨域资源共享(Cross-Origin Resources Sharing,CORS),它是浏览器的保护机制,只允许网页请求统一域名下的服务,同一域名指=>协议,域名,端口号都要保持一致,如果有一项不同,那么就是跨域请求,在前后端分离的项目中,需要解决跨域的问题。
在SpringSecurity中解决跨域很简单,在配置文件中添加如下配置即可

//跨域
http.cors(withDefaults());
  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringCloud是一款开源的微服务框架,OAuth2是一种授权框架,Vue是一个流行的前端框架,ElementUI是一套基于Vue开发的UI框架。结合这些技术栈进行前后端分离的快速上手项目实战开发,可以提高开发效率和代码的可维护性。 实践中,可以按照以下步骤进行快速上手项目开发: 1. 搭建后端服务:使用SpringCloud搭建微服务架构,并引入Spring SecurityOAuth2来实现认证和授权功能,确保后端接口的安全性。 2. 配置OAuth2服务端:在后端服务中配置OAuth2的服务端,定义认证服务器和资源服务器,配置客户端信息,如客户端ID、客户端密钥等。 3. 开发前端界面:使用Vue构建前端界面,并引入ElementUI来快速搭建页面和组件。利用Vue的组件化开发方式,可以更高效地开发各种交互功能。 4. 实现登录认证:在前端界面中使用OAuth2的授权码模式来实现用户登录认证功能,通过向认证服务器发送请求来获取访问令牌,并将令牌保存到前端的Cookie或localStorage中。 5. 发起请求并解析响应:在前端界面中使用Axios库来发起HTTP请求,并在请求头中携带访问令牌,后端服务器根据令牌进行权限验证。前端收到响应后解析数据,并进行相应的操作。 6. 实现权限控制:根据后端接口的权限设定,在前端界面中进行权限控制,隐藏或禁用没有权限的功能。可以通过在请求头中携带用户的角色信息,与后端进行验证。 7. 编写测试用例:保证代码的质量和功能的稳定性,编写相应的测试用例来进行单元测试和接口测试,确保项目的正确运行。 通过以上步骤,可以快速上手并实战开发SpringCloud、OAuth2、Vue和ElementUI结合的前后端分离项目。不仅可以提高开发效率,还能保证项目的安全性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值