SpringSecurity

一、添加starter

添加starter到pom.xml我们即可得到如下安全性

  • 所有的Http请求路径都需要认证
  • 不需要特定的角色和权限
  • 没有登陆页面
  • 认证过程是通过HTTP basic认证对话框实现的
  • 系统只有一个用户,用户名为user

二、保证应用安全性的基本实现

  1. 通过登录页面来进行认证。
  2. 提供一个注册页面,注册完成即成为我们用户。
  3. 对不同的请求路径,执行不同的安全规则。比如,主页和注册页面不需要认证。

三、 SpringSecurity存储用户方式

类的注解标识:
@Configuration
@EnableWebSecurity
继承:WebSecurityConfigurerAdapter

3.1 基于内存存储用户

重写方法:configure
参数:AuthenticationManagerBuilder
应用场景:数量有限的几个用户,而且这些用户基本不会发生变化

auth
	.inMemoryAuthentication()
	.withUser("buzz")
	.password("123456");
	.authorities("ROLE_USER");
	.and()
	.withUser("joker")
	.password("123456");
	.authorities("ROLE_USER");

3.2 基于JDBC用户存储

重写方法:configure
参数:AuthenticationManagerBuilder
应用场景:用户存储与关系型数据库中
此方法不建议使用,最好使用自定义用户认证
《Spring实战》p86

3.3 以LDAP作为后端的用户存储

此方法基于spring security内嵌的LDAP服务器进行存储

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .ldapAuthentication()
                .userSearchBase("ou=people")
                .userSearchFilter("(uid={0})")
                .groupSearchBase("ou=groups")
                .groupSearchFilter("member={0}")
                .passwordCompare()
                .passwordEncoder((PasswordEncoder) new BCryptPasswordEncoder())
                .passwordAttribute("passcode")
                .and()
                .contextSource()
                .root("dc=tacocloud,dc=com")
                .ldif("classpath:ldap.ldif");
    }

3.4 自定义用户认证

此方法最适合存储与关系型数据库中。因此,需要好好学习。

自定义用户认证分为以下几个步骤实现

  1. 因为用来存储用户,所以要先构建用户实体
  2. 实现UserDetailsService接口,并实现loadUserByUsername方法。spring security框架需要根据此方法来通过数据库对用户名进行查询,然后对该用户进行安全认证和授权等操作。
  3. 基于第二步我们需要构造dao接口,连接数据库,进而实现查询语句。
  4. 配置springsecurity 添加userDetailsService服务到springsecurity配置中。
  5. 继续配置转码器。(PasswordEncoder

按照上面步骤,首先构造用户实体

@Entity // spring ORM 与 数据库中表名对应
@Data	// lombok 生成setter、getter
@NoArgsConstructor(access = AccessLevel.PRIVATE, force=true)	// lombok 生成一个无参构造方法
@RequiredArgsConstructor	// lombok 提供经过final或@NotNull修饰的没有初始化的字段的参数的构造方法,如果没有也可以无参。
public class User implements Serializable, UserDetails {

    private static final long serialVersionUID = -5629829985398800755L;

    @Id	// jpa 主键声明
    @GeneratedValue(strategy = GenerationType.AUTO) // jpa 该键策略为自增
    private Long id;
    private final String username;
    private final String password;
    private final String fullname;
    private final String street;
    private final String city;
    private final String state;
    private final String zip;
    private final String phoneNumber;
       
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

实现了UserDetails的接口,为spring security框架提供了更为详细的用户安全信息。

接着,实现UserDetailService接口

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    private UserDAO userDAO;

    public UserDetailsServiceImpl(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    ;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userDAO.findByUsername(username);
        if (user != null) {
            return user;
        }
        throw new UsernameNotFoundException(
                "User '" + username + "' not found");
    }
}

如果存在就添加,如果不存在就抛出UsernameNotFoundException异常。

然后,配置security

	@Bean	// 此注解会将下面方法的返回值被注册为spring bean到spring应用上下文中
    public PasswordEncoder encoder() {
        return new StandardPasswordEncoder("53cr3t");
    }

    @Autowired
    private UserDetailsService userDetailsService;

    /**
     * 自定义用户认证
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)	// 使用我们实现的用户详情服务作为springsecurity对数据库用户数据进行安全认证的途径。
                .passwordEncoder(encoder());	// springsecurity拿到用户数据后要对密码进行转码。
    }

最后,自定义登录页面,进而post表单内容到登录页面url,进行springsecurity框架的安全认证。

四、自定义登录页面

默认的,spring security会为我们提供一个对话框作为登录页面。
当我们实现了SpringSecurity配置(继承WebSecurityConfigurerAdapter)时候,会为我们提供一个默认的登录页面。
但是往往我们要使用我们自己的登录页面,因为默认的登录页面太丑了。。。

废话不多说,上代码。

	@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .formLogin()
                .loginPage("/login")	//配置登录页面(由于登录很少controller代码,可以在webspirngmvc中配置此url对应的视图模板页面
	                .defaultSuccessUrl("/design", true)	// 默认登录成功跳转页面,true为强制跳转
                .and()	// 连接,进行下一个策略配置
                .logout()	// 登出(清空session内容)
                .logoutUrl("/")	// 配置登出的跳转url
        ;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值