spring-security-debug日记

博客主要解决了Spring Security相关的问题:前端页面因'X-Frame-Options'设置拒绝显示;空指针异常出现在SecurityUser.getAuthorities方法;以及前端传参为null导致的问题。通过添加配置、检查UserServiceDetailsImpl类中的权限和更改获取表单数据方式成功修复问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、前端页面报错:index.html:1 Refused to display ‘http://localhost:8080/admin-list.html’ in a frame because it set ‘X-Frame-Options’ to ‘deny’.

后端可以查询
在这里插入图片描述

网上查询说是跨域问题;
添加此配置

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends DefaultWebSecurityConfigurer {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.headers().frameOptions().sameOrigin();  //这里

    }
}

解决问题!
大功告成
成功访问!
在这里插入图片描述

2、空指针异常

java.lang.NullPointerException: null
at com.book.pojo.vo.SecurityUser.getAuthorities(SecurityUser.java:33) ~[classes/:na]
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.createSuccessAuthentication(AbstractUserDetailsAuthenticationProvider.java:197) ~[spring-security-core-5.5.1.jar:5.5.1]
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.createSuccessAuthentication(DaoAuthenticationProvider.java:122) ~[spring-security-core-5.5.1.jar:5.5.1]
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:168) ~[spring-security-core-5.5.1.jar:5.5.1]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182) ~[spring-security-core-5.5.1.jar:5.5.1]
at com.book.filter.LoginFilter.attemptAuthentication(LoginFilter.java:51) ~[classes/:na]

debug模式下查找,原来是在UserServiceDetailsImpl类中,重写的方法中,要返回的对象的权限没有添加进去。

package com.book.service.impl;

import com.book.mapper.ManagerMapper;
import com.book.pojo.po.Manager;
import com.book.pojo.po.Role;
import com.book.pojo.vo.SecurityUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service("userDetailService")
public class UserDetailServiceImpl implements UserDetailsService {

    @Autowired
    MANAGERervice manageRervice;

    @Autowired(required = false)
    ManagerMapper managerMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Manager manager=manageRervice.getByName(username);
        if(manager==null)
            return null;
        SecurityUser user=new SecurityUser();
        user.setCurrentUserInfo(manager);
        List<Role> roles = managerMapper.getRoleByName(username);
        List<String> authorities=new ArrayList<>();
        roles.forEach((role)->{
            authorities.add(role.getRole());
        });
        //此处没有将权限添加进去===========
        user.setPermissionValueList(authorities);
        //=================================
        return user;
    }
}

3、参数为空

前段传递到后端的数值为null
报错的代码:

package com.grand.security.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.grand.security.entity.SecurityUser;
import com.grand.security.entity.User;
import com.grand.security.security.TokenManager;
import com.grand.utils.utils.R;
import com.grand.utils.utils.ResponseUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {
    private TokenManager tokenManager;
    private RedisTemplate redisTemplate;
    private AuthenticationManager authenticationManager;
    public TokenLoginFilter(AuthenticationManager authenticationManager, TokenManager tokenManager, RedisTemplate redisTemplate){
        this.authenticationManager=authenticationManager;
        this.redisTemplate=redisTemplate;
        this.tokenManager = tokenManager;
        this.setPostOnly(false);

        //配置登录url
        this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/acl/login","POST"));

    }

    //获取表单提交的用户名和密码
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        //获取表单提交数据
        try{
            User user = new ObjectMapper().readValue(request.getInputStream(),User.class);
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword(),new ArrayList<>()));

        }catch (IOException e){
            e.printStackTrace();
            throw  new RuntimeException();
        }

    }

    //2、认证成功调用的方法

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
    //认证成功 得到认证之后用户信息
        SecurityUser user  =(SecurityUser) authResult.getPrincipal();


        //根据用户名生成token
        String token = tokenManager.createToken(user.getCurrentUserInfo().getUsername());
        //将用户名称和权限列表放到redis中
        redisTemplate.opsForValue().set(user.getCurrentUserInfo().getUsername(),user.getPermissionValueList());
        //返回token
        ResponseUtil.out(response, R.ok().data("token",token));
    }

    //3、认证呢个失败调用的方法

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        ResponseUtil.out(response,R.error());
    }
}

原来是这个方法有问题,导致了异常。 User user = new ObjectMapper().readValue(request.getInputStream(),User.class);

因此使用另一方法获取表单数据:
修改替换为:
Manager user=new Manager();
user.setUsername(request.getParameter(“username”));
user.setPassword(request.getParameter(“password”));
之后再无报错了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值