专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

Spring Security + OAuth的微信生态完全实战 2

说说 Spring Security

1 : 解决安全性的两种手段

Spring security通常从两个角度解决安全性问题。

  • 使用servlet规范中的filter保护web请求并限制url级别的访问。
  • 使用AOP保护方法的调用。借助于对象代理和使用通知,确保只有具备适当权限的用户才能访问安全访问的方法。

2 : 过滤web请求

DelegatingFilterProxy是一个特殊的servlet filter。它会拦截发往应用中的请求,并将工作委托给一个javax.servlet.filter实现类。这个实现类作为一个bean注册在spring应用的上下文中。

109_1.png DelegatingFilterProxy把Filter的处理逻辑委托给spring应用上下文中所定义的一个代理filter bean

这个filter bean叫做springSecurityFilterChain。它是一个特殊的filter,可以链接一个或多个的其他filter。Spring security依赖一系列的servlet filter来提供不同的安全特性。

3 : 如何实现

在spring应用上下文中,任何实现了WebSecurityConfigurer的bean都可以用来配置spring security。

public interface WebSecurityConfigurer<T extends SecurityBuilder<Filter>> extends SecurityConfigurer<Filter, T> {
}

实际上是通过实现父接口security configurer中的configure来实现security的功能的。

public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {
    void init(B var1) throws Exception;

    void configure(B var1) throws Exception;
}

更常见的实现这一接口的方式是扩展WebSecurityConfigurerAdapter。通过重载Adapter中的3个configure()方法来配置web安全性。

109_2.png 重载WebSecurityConfigurerAdapter的configure方法

4 : HttpSecurity请求管理

/**
 * Security配置
 *
 * @author yanghaolei
 */
@Configuration
@AllArgsConstructor
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

/**
     * configure(HttpSecurity)方法定义了哪些URL路径应该被保护,哪些不应该
     * 参数说明:http://www.spring4all.com/article/419
     * @param http
     */
    @Override
    @SneakyThrows
    protected void configure(HttpSecurity http) {
        http.authorizeRequests()
            .anyRequest().authenticated()
            .and().formLogin().and().httpBasic();
    }

}

  • Http Configure: 默认配置为http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().httpBasic()。通过调用authorizedRequests()和anyResquest().authenticated()要求所有进入的http请求都进行认证。

5: 用户储存

  • 认证过程需要用户资料支撑。就好像去米其林餐厅吃饭的时候我们需要预约,到餐厅的时候服务员会检查名单上是否有我们的名字。如果有名字才会允许我们进入。这个用户名单就是spring security进行认证决策的依据。security同时支持内存,关系型数据库,ldap多种方式来存放用户。一般业务中都需要构建自定义的userDetail配合存放。
  • 在configurer中传入AuthenticationManagerBuilder作为参数。简单调用withUser()方法就可以添加新用户。
    /**
     * @author yanghaolei
     */
    @Bean
    @SneakyThrows
    public void authenticationManagerBean(AuthenticationManagerBuilder authenticationManagerBuilder) {
         authenticationManagerBuilder.inMemoryAuthentication().withUser("user").password("password").roles("student")
                .and().withUser("admin").password("password").roles("student,admin");

    }

  • 配置自定义的用户配合数据库实现用户存储。核心就是实现 UserDetailsService接口中的loadUserByUsername()方法。这一方法返回accessToken构筑必需的user。
public UserDetails loadUserByUsername(String username) {
        Cache cache = cacheManager.getCache(SecurityConstants.USER_DETAILS);
        if (cache != null && cache.get(username) != null) {
            return (User) cache.get(username).get();
        }

        UserDetails userDetails = getUserDetails(result);
        cache.put(username, userDetails);
        return userDetails;
    }

    /**
     * 构建userdetails
     *
     * @param userInfo 用户信息
     * @return
     */
    private UserDetails getUserDetails(UserInfo userInfo) {
        // 1 数据库读取
        Set<String> dbAuthsSet = new HashSet<>();
        if (ArrayUtil.isNotEmpty(userInfo.getRoles())) {
            // 获取角色
            Arrays.stream(userInfo.getRoles()).forEach(roleId -> dbAuthsSet.add(SecurityConstants.ROLE + roleId));
            // 获取资源
            if (ObjectUtil.isNotNull(userInfo.getPermissions())) {
                dbAuthsSet.addAll(Arrays.asList(userInfo.getPermissions()));
            }

        }
        // 2 获取user
        Collection<? extends GrantedAuthority> authorities
                = AuthorityUtils.createAuthorityList(dbAuthsSet.toArray(new String[0]));
        User user = userInfo.getUser();
        boolean enabled = (user.getLockFlag().equals(LockFlagEnum.NO)) ? true : false;

        // 构造security用户
        return new User(user.getId(), user.getMobile(),
                SecurityConstants.BCRYPT + user.getPassword(), true,
                true, true, true, authorities);
    }

  • 成功返回userDetails 可以发放accessToken了。

文章永久链接:https://tech.souyunku.com/26026

未经允许不得转载:搜云库技术团队 » Spring Security + OAuth的微信生态完全实战 2

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们