为了账号安全,请及时绑定邮箱和手机立即绑定

Spring Boot 安全性 - 在 Web 服务调用中显示自定义身份验证失败消息

Spring Boot 安全性 - 在 Web 服务调用中显示自定义身份验证失败消息

手掌心 2023-03-31 09:29:25
当用户尝试使用暂停、锁定或无效的帐户调用我的网络服务时,我试图显示自定义错误。问题是,无论我尝试什么,相同的消息不断返回:“访问此资源需要完全身份验证”我的 CustomUserDetailsService 是这样的:@Servicepublic class CustomUserDetailsService implements UserDetailsService {    private static final Logger logger = LogManager.getLogger(CustomUserDetailsService.class);    private @Autowired CredentialsServiceQuery credentials;    private @Autowired MemberProfile memberProfile;    @Override    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {        User.UserBuilder builder = null;        try {            boolean exists = credentials.checkUserExists(username);            if (exists) {                memberProfile = credentials.getUserInformation(username);                builder = User.withUsername(username);                builder.password(memberProfile.getPassword());                builder.authorities(getGrantedAuthorities());                logger.info("User exists: {}", username);            } else {                throw new UsernameNotFoundException(SpringSecurityMessageSource.getAccessor().getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", new Object[] {username}, "User credentials is wrong"));            }        } catch (Exception ex) {            throw new UsernameNotFoundException(SpringSecurityMessageSource.getAccessor().getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", new Object[] {username}, "User credentials is wrong"));            //throw new UsernameNotFoundException("An error occured while trying to find the username, " + username, ex);        }        return builder.build();    }    private List<GrantedAuthority> getGrantedAuthorities(){        List<GrantedAuthority> authorities = new ArrayList<>();        authorities.clear();                authorities.add(new SimpleGrantedAuthority("ROLE_USER"));        return authorities;    }}
查看完整描述

1 回答

?
素胚勾勒不出你

TA贡献1827条经验 获得超9个赞

我不得不放弃尝试让 Spring Security 自动为入口点提供来自用户详细信息服务的异常消息的想法。


因此,我改用自定义身份验证提供程序以获得更多控制,并引入了一个名为 ErrorMessage 的自定义服务:


@Getter

@Setter

@ToString

@Service

public class ErrorMessage {

    private String status;

    private String message;

}

@Getter、@Setter 和@ToString 注释来自 lombok。他们做到了,所以我不必编写 setter 和 getter 以及 toString 方法。


在我的自定义身份验证提供程序中,我只是这样设置错误消息:


private @Autowired ErrorMessage errorMessage;    

@Override

        public Authentication authenticate(Authentication authentication) throws AuthenticationException {

            try {

                String username = authentication.getName();

                String password = authentication.getCredentials().toString();


                if (!credentials.checkUserExists(username)) {

                    //set something here

                }


                memberProfile = credentials.getUserInformation(username);


                if (passwordEncoder.matches(password, memberProfile.getPassword())) {

                    logger.info("It matches - encoder!");

                    return new UsernamePasswordAuthenticationToken(username, password, getGrantedAuthorities());

                } else {

                    //error message bean utilised here

                    errorMessage.setStatus("100");

                    errorMessage.setMessage(username + "'s password is incorrect");


                    throw new BadCredentialsException("The credentials provided are incorrect");

                }

            } catch (Exception ex) {

                throw new BadCredentialsException("The credentials provided are incorrect", ex);

            }

        }

然后我以这种方式在入口点获得自定义错误消息:


@Component

public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {

    private @Autowired ErrorMessage errorMessage;


    @Override

    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException ex) throws IOException, ServletException {

        //String json = String.format("{\"errorcode\": \"%s\", \"message\": \"%s\"}", response.getStatus(), ex.getMessage());

        String json = String.format("{\"errorcode\": \"%s\", \"message\": \"%s\"}", errorMessage.getStatus(), errorMessage.getMessage());

        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

        response.setContentType("application/json");

        response.setCharacterEncoding("UTF-8");

        response.getWriter().write(json);

    }

}


查看完整回答
反对 回复 2023-03-31
  • 1 回答
  • 0 关注
  • 105 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信