当前位置: 代码网 > it编程>编程语言>Java > Spring Security自定义失败处理器问题

Spring Security自定义失败处理器问题

2024年08月01日 Java 我要评论
spring security自定义失败处理器我们还希望在认证失败或者是授权失败的情况下也能和我们的接口一样返回相同结构的json,这样可以让前端能对响应进行统一的处理。要实现这个功能我们需要知道sp

spring security自定义失败处理器

我们还希望在认证失败或者是授权失败的情况下也能和我们的接口一样返回相同结构的json,这样可以让前端能对响应进行统一的处理。要实现这个功能我们需要知道springsecurity的异常处理机制。

在springsecurity中,如果我们在认证或者授权的过程中出现了异常会被exceptiontranslationfilter捕获到。在exceptiontranslationfilter中会去判断是认证失败还是授权失败出现的异常。

  • 如果是认证过程中出现的异常会被封装成authenticationexception然后调用authenticationentrypoint对象的方法去进行异常处理。
  • 如果是授权过程中出现的异常会被封装成accessdeniedexception然后调用accessdeniedhandler对象的方法去进行异常处理。

所以如果我们需要自定义异常处理,我们只需要自定义authenticationentrypoint和accessdeniedhandler然后配置springsecurity即可。

在spring security中,你可以通过实现特定的接口来自定义认证失败处理器(authenticationfailurehandler)和授权失败处理器(accessdeniedhandler)。以下是如何分别自定义它们的步骤:

一、自定义认证失败处理器(authenticationfailurehandler)

  • 1.1创建自定义的authenticationfailurehandler
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import org.springframework.security.core.authenticationexception;
import org.springframework.security.web.authentication.authenticationfailurehandler;

public class customauthenticationfailurehandler implements authenticationfailurehandler {

    @override
    public void onauthenticationfailure(httpservletrequest request, httpservletresponse response,
                                        authenticationexception exception) throws ioexception, servletexception {
        // 在这里处理认证失败的情况
        response.setstatus(httpservletresponse.sc_unauthorized);
        response.getwriter().write("登录失败: " + exception.getmessage());
    }
}
  • 1.2在spring security配置中使用你的自定义认证失败处理器
@override
protected void configure(httpsecurity http) throws exception {
    http
        // ... 其他配置 ...
        .formlogin()
            .failurehandler(new customauthenticationfailurehandler()) // 设置自定义认证失败处理器
            // ... 其他表单登录配置 ...
        // ... 其他http安全配置 ...
    ;
}

二、自定义授权失败处理器(accessdeniedhandler)

  • 2.1创建自定义的accessdeniedhandler
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import org.springframework.security.access.accessdeniedexception;
import org.springframework.security.web.access.accessdeniedhandler;

public class customaccessdeniedhandler implements accessdeniedhandler {

    @override
    public void handle(httpservletrequest request, httpservletresponse response,
                       accessdeniedexception accessdeniedexception) throws ioexception, servletexception {
        // 在这里处理授权失败的情况
        response.setstatus(httpservletresponse.sc_forbidden);
        response.getwriter().write("权限不足: " + accessdeniedexception.getmessage());
    }
}
  • 2.2在spring security配置中使用你的自定义授权失败处理器
@override
protected void configure(httpsecurity http) throws exception {
    http
        // ... 其他配置 ...
        .exceptionhandling()
            .accessdeniedhandler(new customaccessdeniedhandler()) // 设置自定义授权失败处理器
        // ... 其他异常处理配置 ...
        // ... 其他http安全配置 ...
    ;
}

三、实战

我们还希望在认证失败或者是授权失败的情况下也能和我们的接口一样返回相同结构的json,这样可以让前端能对响应进行统一的处理。要实现这个功能我们需要知道springsecurity的异常处理机制。

在springsecurity中,如果我们在认证或者授权的过程中出现了异常会被exceptiontranslationfilter捕获到。在exceptiontranslationfilter中会去判断是认证失败还是授权失败出现的异常。

  • 如果是认证过程中出现的异常会被封装成authenticationexception然后调用authenticationentrypoint对象的方法去进行异常处理。
  • 如果是授权过程中出现的异常会被封装成accessdeniedexception然后调用accessdeniedhandler对象的方法去进行异常处理。

所以如果我们需要自定义异常处理,我们只需要自定义authenticationentrypoint和accessdeniedhandler然后配置springsecurity即可。

(com.sangeng.handler)

  • 自定义认证失败处理器:
@component
public class authenticationentrypointimpl implements authenticationentrypoint {
    @override
    public void commence(httpservletrequest request, httpservletresponse
            response, authenticationexception authexception) throws ioexception,
            servletexception {
        responseresult result = new
                responseresult(httpstatus.unauthorized.value(), "认证失败请重新登录");
        string json = json.tojsonstring(result);
        webutils.renderstring(response, json);
    }
}
  • 自定义授权失败处理器:
@component
public class accessdeniedhandlerimpl implements accessdeniedhandler {
    @override
    public void handle(httpservletrequest request, httpservletresponse response,
                       accessdeniedexception accessdeniedexception) throws ioexception,
            servletexception {
        responseresult result = new responseresult(httpstatus.forbidden.value(),
                "权限不足");
        string json = json.tojsonstring(result);
        webutils.renderstring(response, json);
    }
}
  • 修改配置类:
@configuration //配置类
@enablewebsecurity // 开启spring security的功能 代替了 implements websecurityconfigureradapter
public class securityconfig {
    @autowired
    authenticationconfiguration authenticationconfiguration;//获取authenticationmanager
    @autowired
    jwtauthenticationtokenfilter jwtauthenticationtokenfilter;
    @autowired
    accessdeniedhandlerimpl accessdeniedhandler;
    @autowired
    authenticationentrypointimpl authenticationentrypoint;


    @bean
    public passwordencoder passwordencoder() {
        return new bcryptpasswordencoder();
    }

    @bean
    public authenticationmanager authenticationmanagerbean() throws exception {
        return authenticationconfiguration.getauthenticationmanager();
    }

    /**
     * 配置spring security的过滤链。
     *
     * @param http 用于构建安全配置的httpsecurity对象。
     * @return 返回配置好的securityfilterchain对象。
     * @throws exception 如果配置过程中发生错误,则抛出异常。
     */
    @bean
    securityfilterchain securityfilterchain(httpsecurity http) throws exception {
        http
                // 禁用csrf保护
                .csrf(csrf -> csrf.disable())
                // 设置会话创建策略为无状态
                .sessionmanagement(session -> session.sessioncreationpolicy(sessioncreationpolicy.stateless))
                // 配置授权规则                 指定user/login路径.允许匿名访问(未登录可访问已登陆不能访问). 其他路径需要身份认证
                .authorizehttprequests(auth -> auth.requestmatchers("/user/login").anonymous().anyrequest().authenticated())
                //开启跨域访问
                .cors(abstracthttpconfigurer::disable)
                // 添加jwt认证过滤器
                .addfilterbefore(jwtauthenticationtokenfilter, usernamepasswordauthenticationfilter.class)
                // 配置异常处理
                .exceptionhandling(exception -> exception.accessdeniedhandler(accessdeniedhandler).authenticationentrypoint(authenticationentrypoint));


        // 构建并返回安全过滤链
        return http.build();
    }

注意事项

  • 确保你的认证和授权失败处理器都正确实现了相应的接口,并且正确设置了它们的状态码和响应内容。
  • 你可以将你的自定义处理器作为spring bean注入到你的配置中,而不是直接在配置方法中创建新的实例。这样可以更好地管理你的spring应用程序中的bean。
  • 在处理认证和授权失败时,你可能希望返回json而不是纯文本响应,特别是在构建restful api时。为此,你可以使用@responsebody注解或responseentity类来构建json响应。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com