其他分享
首页 > 其他分享> > spring security使用和原理简析(2)

spring security使用和原理简析(2)

作者:互联网

转自https://pjmike.github.io/2018/10/12/%E6%B5%85%E6%9E%90Spring-Security-%E6%A0%B8%E5%BF%83%E7%BB%84%E4%BB%B6/

上一篇我们主要讲述了如何搭项目,这里我们就来简单探究一下原理

 

Spring Security的核心类

Spring Security的核心类主要包括以下几个:

SecurityContextHolder、Securityontext和Authentication

SecurityContextHolder用于存储安全上下文(security context)的信息,即一个存储身份信息,认证信息等的容器。SecurityContextHolder默认使用 ThreadLocal策略来存储认证信息,即一种与线程绑定的策略,每个线程执行时都可以获取该线程中的 安全上下文(security context),各个线程中的安全上下文互不影响。而且如果说要在请求结束后清除安全上下文中的信息,利用该策略Spring Security也可以轻松搞定。

因为身份信息时与线程绑定的,所以我们可以在程序的任何地方使用静态方法获取用户信息,一个获取当前登录用户的姓名的例子如下:

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {
String username = ((UserDetails)principal).getUsername();
} else {
String username = principal.toString();
}
View Code

 

getAuthentication()方法返回了认证信息,准确的说是一个 Authentication实例,Authentication是 Spring Security 中的一个重要接口,直接继承自 Principal类,该接口表示对用户身份信息的抽象,接口源码如下:

public interface Authentication extends Principal, Serializable { 
    //权限信息列表,默认是 GrantedAuthority接口的一些实现
    Collection<? extends GrantedAuthority> getAuthorities(); 
    //密码信息,用户输入的密码字符串,认证后通常会被移除,用于保证安全
    Object getCredentials();
    //细节信息,web应用中通常的接口为 WebAuthenticationDetails,它记录了访问者的ip地址和sessionId的值
    Object getDetails();
    //身份信息,返回UserDetails的实现类
    Object getPrincipal();
    //认证状态,默认为false,认证成功后为 true
    boolean isAuthenticated();
    //上述身份信息是否经过身份认证 
    void setAuthenticated(boolean var1) throws IllegalArgumentException;
}
View Code

 

AuthenticationManager、ProviderManager 和 AuthenticationProvider

框架用来实现登录的功能

待明确源码

UserDetailsService 和 UserDetails

UserDetailsService简单说就是加载对应的UserDetails的接口(一般从数据库),而UserDetails包含了更详细的用户信息,定义如下:

public interface UserDetails extends Serializable {

   Collection<? extends GrantedAuthority> getAuthorities();

   String getPassword();

   String getUsername();

   boolean isAccountNonExpired();

   boolean isAccountNonLocked();

   boolean isCredentialsNonExpired();

   boolean isEnabled();
}
View Code

UserDetails 接口与 Authentication接口相似,它们都有 username、authorities。它们的区别如下:

认证过程的官方样例

public class SpringSecuriryTestDemo {
    private static AuthenticationManager am = new SampleAuthenticationManager();

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        while (true) {
            System.out.println("Please enter your username:");
            String name = in.readLine();
            System.out.println("Please enter your password:");
            String password = in.readLine();
            try {
                Authentication request = new UsernamePasswordAuthenticationToken(name, password);
                Authentication result = am.authenticate(request);
                SecurityContextHolder.getContext().setAuthentication(request);
                break;
            } catch (AuthenticationException e) {
                System.out.println("Authentication failed: " + e.getMessage());
            }
        }
        System.out.println("Successfully authenticated. Security context contains: " + SecurityContextHolder.getContext().getAuthentication());
    }
    static class SampleAuthenticationManager implements AuthenticationManager {
        static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();
        static {
            AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_USER"));
        }
        @Override
        public Authentication authenticate(Authentication authentication) throws AuthenticationException {
            if (authentication.getName().equals(authentication.getCredentials())) {
                return new UsernamePasswordAuthenticationToken(authentication.getName(), authentication.getCredentials(), AUTHORITIES);
            }
            throw new BadCredentialsException("Bad Credentials");
        }
    }
}
View Code

 

结果

Please enter your username:
pjmike
Please enter your password:
123
Authentication failed: Bad Credentials
Please enter your username:
pjmike
Please enter your password:
pjmike
Successfully authenticated. 
Security context contains: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@441d0230:
Principal: pjmike; 
Credentials: [PROTECTED];
Authenticated: true; Details: null; 
Granted Authorities: ROLE_USER
View Code

 

了解了简单的认证过程,下一篇在看一下spring security的filter chain

标签:spring,Authentication,信息,认证,简析,接口,new,security,UserDetails
来源: https://www.cnblogs.com/jiataoq/p/11073683.html