首页 科技正文

环球ug官网:SpringSecurity(1)---认证+授权代码实现

admin 科技 2020-06-04 45 0

认证+授权代码实现

Spring Security是 一种基于 Spring AOP 和 Servlet 过滤器的平安框架。它提供周全的平安性解决方案,同时在 Web 请求级和方式挪用级处置身份确认和授权。

有关认证和授权的理论知识,之前有写过相关博客。领会权限治理

一、SpringSceurity事情流程

网上找一张图,以为画的挺好的,对照容易明白。否则换的是源码流程图很难去明白。

图片地址 : 地址 可以单机放大看加倍清晰

要想明白这张图建议看下这篇博客,由于这张图中需要自界说的My...类,在文章中都有说明,以是更好明白点。

Spring Boot Security 详解


二、认证+授权代码

这里只展示一些焦点代码,详细完整代码放在github上。

1、UserDetails接口

Security 中的用户接口,我们自界说用户类要实现该接口, 用于向security中注入当前用户的姓名密码,和拥有的角色。同时也包罗一些其它信息,好比当前用户是否过时,

账号是否锁定等等。

自己界说User实现这个接口

public class User implements UserDetails {
    private String username;
    private String password;
    private List<Role> roles;
    /**
     * 获取用户名
     */
    @Override
    public String getUsername() {
        return username;
    }
    /**
     * 获取密码
     */
    @Override
    public String getPassword() {
        return password;
    }
    /**
     * 用户的权限集, 默认需要添加ROLE_ 前缀
     */
    @Override
    @JsonIgnore
    public List<GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (Role role : roles) {
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getName()));
        }
        return authorities;
    }
    /**
     * 账户是否过时
     */
    @Override
    @JsonIgnore
    public boolean isAccountNonExpired() {
        return true;
    }
    /**
     * 账户是否锁定
     */
    @Override
    @JsonIgnore
    public boolean isAccountNonLocked() {
        return true;
    }
    /**
     * 凭证是否过时
     */
    @Override
    @JsonIgnore
    public boolean isCredentialsNonExpired() {
        return true;
    }
    /**
     * 用户是否可用
     */
    @Override
    public boolean isEnabled() {
        return true;
    }  
}

2、UserDetailsService

Security 中的用户 Service,自界说用户服务类需要实现该接口。这个接口只有一个方式需要我们去实现,那就是通过用户名去获取用户信息。这里也是和数据库交互获取

用户认证和授权信息的地方。

@Service
@Slf4j
public class UserService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        //TODO 正常应该查询数据库获取用户和用户的权限
//        User user = userMapper.loadUserByUsername(userName);
//        List<Role> roles = rolesMapper.getRolesByUid(user.getId());
//        user.setRoles(roles);
        log.info("上岸用户名: {}", userName);
        //通过用户名查询到的密码 密码肯定是加密过的 这里明文密码是 123456
        String password = "e10adc3949ba59abbe56e057f20f883e";
        //用户对应权限
        List<Role> roles = Lists.newArrayList(new Role(1L, "西席"), new Role(2L, "学生"));
        User user = new User(userName, password, roles);
        return user;
    }
}

注重 这里的明文密码是 123456,也就是用户输入这个才气完成认证。授权的话当前用户有两个角色 西席学生。在下面测试的时刻会用到。

3、WebSecurityConfigurerAdapter

它是Spring Security的Java 设置类。建立类SecurityConfiguration继续 WebSecurityConfigurerAdapter,来对我们应用中所有的平安相关的事项(

所有url,验证用户名密码,表单重定向等)举行控制。

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 1、设置的是认证信息, AuthenticationManagerBuilder 这个类,就是AuthenticationManager的制作者, 我们只需要向这个类中, 设置用户信息,
     *    就能天生对应的AuthenticationManager, 这个类也提过,是用户身份的治理者, 是认证的入口, 因此,我们需要通过这个设置,想security提供真实的用户身份。
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    }
    /**
     * 2、设置Security的认证计谋, 每个模块设置使用and末端。这个也是最庞大的
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    }
    /**
     * 3、这个设置方式用于设置静态资源的处置方式,可使用 Ant 匹配规则。就是可以不用认证就可以直接接见的接口
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
    }
}

完整示例

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;
    /**
     * 密码验证器
     */
    @Autowired
    private PassWordEncorder passWordEncorder;
    /**
     * 乐成处置器
     */
    @Autowired
    private AuthenctiationSuccessHandler authenctiationSuccessHandler;

    /**
     * 失败处置器
     */
   @Autowired
   private AuthenctiationFailHandler authenctiationFailHandler;
   /**
    * 向Security注入用户信息
    */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passWordEncorder);
    }
    /**
     * 设置规则
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //开启上岸设置
        http.authorizeRequests()
                // 登录之后就能接见
                .antMatchers("/no-authorize").authenticated()
                // 上岸后 需要校长角色权限
                .antMatchers("/need-authorize").hasRole("校长")
                // 其他的路径都是登录后即可接见
                .anyRequest().authenticated()
                .and().formLogin()
                // 界说登录页面,未登录时,接见一个需要登录之后才气接见的接口,会自动跳转到该页面
                .loginPage("/login_page")
                //登录乐成的处置器
                .successHandler(authenctiationSuccessHandler)
                //登录失败的处置器
                .failureHandler(authenctiationFailHandler)
                // 登录处置接口
                .loginProcessingUrl("/login")
                // 界说登录时,用户名的 key,默以为 username
                .usernameParameter("username")
                //界说登录时,用户密码的 key,默以为 password
                .passwordParameter("password").permitAll()
                .and().logout()
                ////和表单登录相关的接口一切都直接通过
                .permitAll()
                .and().csrf().disable().exceptionHandling().accessDeniedHandler(getAccessDeniedHandler());
    }

    /**
     * 对于/static/  下的路径都不用认证
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/no-login");
    }

    /**
     * 用户未认证异常阻挡
     */
    @Bean
    AccessDeniedHandler getAccessDeniedHandler() {
        return new AuthenticationAccessDeniedHandler();
    }
}

注重 这里一共设置了三个路径用于测试。

1、/no-login 接口不需要认证就可以直接接见
2、/no-authorize 需要认证 但不需要授权就可以接见
3、/need-authorize 首先需要认证 认证通过还需要授权 这里需要校长的角色才可以接见该接口 然则我们测试用户只有西席和学生以是没有权限接见该接口

下面会针对这个个接口划分举行测试。


三、测试

1、接口提供

@RestController
public class TestController {

    /**
     * 1、不需要上岸就可以接见
     */
    @RequestMapping(value = "/no-login")
    public ServiceResponse noLogin() {
        return ServiceResponse.success("迎接接见不需要上岸接口");
    }
    /**
     * 2、只上岸,不许认证接口
     */
    @RequestMapping(value = "/no-authorize")
    public ServiceResponse needAuthorize(){
        return ServiceResponse.success("上岸了 不用授权");
    }
    /**
     * 3、上岸 + 相关认证接口
     */
    @RequestMapping(value = "/need-authorize")
    public ServiceResponse noAuthorize() {
        return ServiceResponse.success("上岸+授权乐成");
    }
    /**
     * @Description: 若是自动跳转到这个页面,说明用户未登录,返回响应的提醒即可
     */
    @RequestMapping("/login_page")
    public ServiceResponse loginPage() {
        return  ServiceResponse.failure("001", "尚未登录,请登录!");
    }
}

2、未登录接见 no-login 和 no-authorize 接口

no-login接口

很明显没有上岸 请求该接口乐成!

no-authorize接口

没有上岸接见失败,在上面设置了若是用户没有认证的话跳转到login_page接口,以是这里返回 '尚未登录,请登录!'

3、上岸后接见 no-authorize 和 need-authorize 接口

先上岸

凭据上面设置上岸的路径为 /login 请求参数包罗 usernamepassword

注重 这里需要post请求。

no-authorize 接口

上岸就可以接见了。

need-authorize 接口

虽然上岸乐成了,然则由于该接口需要校长角色,之前给该用户只设置了西席和学生的角色以是接见失败。


参考

1、SpringSide 3 中的平安框架

2、Spring Security 事情原理概览

3、Spring Boot Security 详解 很赞



别人骂我胖,我会生气,由于我心里承认了我胖。别人说我矮,我就会以为可笑,由于我心里知道我不可能矮。这就是我们为什么会对别人的攻击生气。
攻我盾者,乃我心里之矛(17)
,

欧博注册网址

www.cx11yj.cn欢迎进入欧博网址(Allbet Gaming),欧博网址开放会员注册、代理开户、电脑客户端下载、苹果安卓下载等业务。

版权声明

本文仅代表作者观点,
不代表本站Sunbet的立场。
本文系作者授权发表,未经许可,不得转载。

评论