Spring-security提供的认证方式(一)

  AuthenticationProvider

 

public interface AuthenticationProvider {
    Authentication authenticate(Authentication authentication) throws AuthenticationException;
    boolean supports(Class<?> authentication);
}

   该接口是开始认证的入口,传入用户输入的用户名密码到authenticate方法中进行验证,通过认证就返回用户完整的信息,若认证过程中有任何的错误,就直接抛出AuthenticationException。接下来实现一个简单的AuthenticationProvider:

 

 1. 项目security.xml中添加如下代码:

<security:authentication-manager>
     <security:authentication-provider ref='myAuthenticationProvider'/>
</security:authentication-manager>

 

 2. 创建java类MyAuthenticationProvider 实现AuthenticationProvider接口:

 

@Component
public class MyAuthenticationProvider implements AuthenticationProvider {
    @Override
    public boolean supports(Class<?> authentication) {
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String username = authentication.getName();
        String password = authentication.getCredentials().toString();
        if (!"silentwu".equals(username)) {
            throw new UsernameNotFoundException("用户不存在");
        }
        if (!"123456".equals(password)) {
            throw new BadCredentialsException("密码错误");
        }
        return new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(),
                Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
    }
}

 

   用户在登录界面中输入用户名:silentwu  密码:123456   那么通过认证,否则返回对应的错误信息。

 

  UserDetailsService

   

public interface UserDetailsService { 
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

   这个接口是认证过程的重要接口,只有一个方法,就是通过用户的唯一标识获取到用户的完整信息,包括密码和权限等。接着来看一个简单的实现:

 

 

 

 1. 在security.xml中添加如下代码:

 

<security:authentication-manager>
    <security:authentication-provider user-service-ref='myUserDetailsService'/>
</security:authentication-manager>

 

    2.   创建Java类MyUserDetailsService ,实现UserDetailsService

@Component
public class MyUserDetailsService implements UserDetailsService {
   @Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return new User("silentwu", "123456", Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
    }

}

   在这个类中直接返回一个User对象,用户名是silentwu,密码是123456,对应用户输入的信息是否正确的检测,spring-security已经帮我们检测了

 

  JdbcDaoImpl

   通常情况下我们的用户数据都是存放到数据库中的,那么在用户登录的时候需要查询数据库进行验证,spring-security通过JdbcDaoImpl实现了这个功能,JdbcDaoImpl是UserDetailsService的一个子类。

 

<!--[if !supportLists]-->1.       

         1.   <!--[endif]-->在数据库中执行如下代码:

CREATE TABLE users(
    username VARCHAR(50) NOT NULL PRIMARY KEY,
    PASSWORD VARCHAR(50) NOT NULL,
    enabled BOOLEAN NOT NULL
);

CREATE TABLE authorities (
    username VARCHAR(50) NOT NULL,
    authority VARCHAR(50) NOT NULL,
    CONSTRAINT fk_authorities_users FOREIGN KEY(username) REFERENCES users(username)
);
CREATE UNIQUE INDEX ix_auth_username ON authorities (username,authority);
insert  into `authorities`(`username`,`authority`) values ('silentwu','ROLE_USER');
insert  into `users`(`username`,`password`,`enabled`) values ('silentwu','12345',1);

   

 2. 在security.xml中添加代码:

   <security:authentication-provider>
      <security:jdbc-user-service data-source-ref="securityDataSource"/>
       </security:authentication-provider>
</security:authentication-manager>

 或者

<security:authentication-manager>
    <security:authentication-provider user-service-ref='myUserDetailsService'/>
</security:authentication-manager>
<bean id="myUserDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <property name="dataSource" ref="securityDataSource"/>
</bean>

 这两种方式都是同样的效果

 这样JdbcDaoImpl配置就完成了,很简单。

 原理:

    首先通过用户提交的用户名查询出用户信息,若没有查询到用户,那么就抛出UsernameNotFoundException

    通过查询出来的用户去查询用户的权限表,获取用户的权限

    创建UserDetails,返回

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值