spring-security 常见错误 及简单配置

error-1:

项目加进spring-security后,项目启动后,任何页面都是空白,404...


Solution:

在spring-security.xml配置中

                   login-page="/login.jsp"
                login-processing-url="/login.do"
                default-target-url="/index.jsp"
                authentication-failure-url="/failer.jsp"
                authentication-success-forward-url="/main.jsp"
        />

可能是这一段配置的问题

我是添加了  authentication-success-forward-url="/main.jsp" 之后项目登陆页面出现了


error-2:

 security.authentication.BadCredentialsException: Bad credentials

 Solution:

在spring-security.xml配置文件中配置了对密码的加密方式

作为一个简单Demo,注释掉这一句就好


 error-3:

登陆页面是访问成功了,进入主页面了,但点其他页面 都是 “拒绝访问”

security AccessDeniedException: Access is denied 

  Solution:

在spring-security.xml文件里,配置了可访问的用户    access="ROLE_USER,ROLE_ADMIN,ROLE_user,ROLE_admin"

  ROLE_user,ROLE_admin"/>

我 在userService里边是进行拼接的,

    authorities.add(new SimpleGrantedAuthority("ROLE_"+r.getRoleName()));

结果是因为数据库查询出来用户名是小写的,凭借后就变成了ROLE_user,ROLE_admin;

这里可没有windows-mysql的大小写不敏感,所以权限是匹配不上的

根据数据库查询出的结果,相应的添加后边偏红语句即可

  ROLE_user,ROLE_admin"/>


下面是配置spring-security的一般步骤 :

  • pom.xml

  
    
      org.springframework.security
      spring-security-web
      ${spring.security.version}
    
    
      org.springframework.security
      spring-security-config
      ${spring.security.version}
    
    
      org.springframework.security
      spring-security-core
      ${spring.security.version}
    
    
      org.springframework.security
      spring-security-taglibs
      ${spring.security.version}
    
    

 如果不是使用maven,直接导入相应的jar包进项目就行了

  • web.xml


  
    contextConfigLocation
    classpath:applicationContext.xml,classpath*:spring-security.xml
  



  

    springSecurityFilterChain
    org.springframework.web.filter.DelegatingFilterProxy
  
  
    springSecurityFilterChain
    /*
  

特别要注意web.xml文件,文件里的filter名称是固定的

注意filter-name一定要写成springSecurityFilterChain。在DelegatingFilterProxy类init时,会获取filter-name,然后通过filter-name去spring中获取代理的bean。

  • spring-security.xml   




    
    
    
    
    
    

    
      


        
        
        

        
        
        
        
        
        
        

        
        

        
        

    

    
    
        
            

        
    

    
    

    

  • UserService

在spring-security中      

 

配置登陆控制的service,具体service如下


@Service("userService")
public class UserService implements IUserService {
    @Autowired
    private UserDao userDao;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        UserInfo userInfo = userDao.findByUsername(username);

//        security框架的User对象,将查询出的结果封装其中
//        getAuthority 用户描述
//        User有两个构造函数,1个3参数构造,一个6参数
//        User user = new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthority(userInfo.getRoles()));
        User user = new User(userInfo.getUsername(),
                "{noop}"+userInfo.getPassword(),
                userInfo.getStatus()==1?true:false, //是否可(已启用) enable
                true,              //账户是否 不过期
                true,            //设置为true如果证书 未过期
                true,              //设置为true ,如果账户 没有被锁定
                getAuthority(userInfo.getRoles())); // 权限
//        System.out.println("    用户"+userInfo);
        return user;
    }

    /**
     * 获取用户描述(权限)
     * @return
     */
    List getAuthority(List roles){
        List authorities = new ArrayList<>();
        for (Role r:roles)
        {
            //获取角色名,逐一加入list
            authorities.add(new SimpleGrantedAuthority("ROLE_"+r.getRoleName()));
//            System.out.println(r.getRoleName()+"    角色权限");
        }
//        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        return authorities;

    }
}

UserDao

public interface UserDao {
    /**
        使用的mybatis,可以替代
     *根据用户名查询用户
     * @return
     */
    @Select("select  * from users where username = #{username}")
    UserInfo findByUsername(String username);
}

UserInfo


public class UserInfo {
    private String id;
    private String username;
    private String email;
    private String password;
    private String phoneNum;//电话
    private int status;//状态 : 0 未开启 1 开启
    private String statusStr;
    private List roles;

//   省略getter/setter方法....
}

还需要一个index.jsp页面,登陆成功后会跳转到index.jsp

 在spring-security中可修改成功后跳转位置

authentication-success-forward-url="/index.jsp"

 


附录1----security加密密码

开启security加密密码

在spring-security.xml中加入

   
   
       
           
           
       

   


   

还需要修改的地方:

需要进入UserInfoService中保存用户时,保存密码时,将密码加密后然后存储

@Service("userInfoService")
public class UserInfoService implements IUserInfoService  {
......

@Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;  


    public void save(UserInfo userInfo) {  if(userInfo.getUsername()==null||userInfo.getPassword()==null||userInfo.getUsername()==""||userInfo.getPassword()=="")
        {
            throw new RuntimeException("保存的用户为空");
        }else {
            userInfo.setPassword(bCryptPasswordEncoder.encode(userInfo.getPassword()));
            userDao.save(userInfo);
        }
    }

......

}

删除UserService中的 “{noop}+"。【“{noop}”的意思时不使用加密登陆】

 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

......

User user=new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthority(userInfo.getRoles()));

......

}


数据库加密字段的存储

比较简单的方法是将之前为加密的password字段直接修改密码字段,使用下边这个加密实体类生成对应密码的加密串(动态)

加密实体类Utils

/**
加密结果类
这个类只是能生成密码对应的加密串
*/
public class BCryptPasswordEncoderUtils {
    static BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
    static String encodePassword(String password){
        return  bCryptPasswordEncoder.encode(password);
    }


    public static void main(String[] args) {
//输入:5201314
        Scanner in = new Scanner(System.in);
        String s = in.next();
        String password = encodePassword(s);
        System.out.println(password);
//输出:$2a$10$/6kKRthQCnEgNZ3gm5MiwOnGCeJENokZZ4r1zOKjRXmceZe2xzeI2
    }
}

 

你可能感兴趣的:(spring-security,java,spring)