springsecurity小结

来源:互联网 发布:九九乘法口诀java运算 编辑:程序博客网 时间:2024/05/22 17:26

1.springsecurity主要工作
(1)登录管理
(2)权限管理
1.1登录管理
springsecurity给我们提供了完整的登录机制包括登录错误提示,退出提示以及,开启CSRF防护,所以所有POST表单都必须包含csrf.token.我们只需要去他的官方文档copy他的表单模板然后我们自己定义样式就可以轻松实现登录的功能。无需关心session回话的管理。

` <c:url value="/login" var="loginProcessingUrl"/>   <form action="${loginProcessingUrl}" method="post"><!--    spring security默认开启CSRF防护,所以所有POST表单都必须包含csrf.token -->    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>    <fieldset>        <legend>Please Login</legend>        <!-- use param.error assuming FormLoginConfigurer#failureUrl contains the query parameter error -->        <c:if test="${param.error != null}">            <div>            <!--自定义错误消息  -->                Failed to login.                <c:if test="${SPRING_SECURITY_LAST_EXCEPTION != null}">                  Reason: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />                </c:if>            </div>        </c:if>        <!-- the configured LogoutConfigurer#logoutSuccessUrl is /login?logout and contains the query param logout -->        <c:if test="${param.logout != null}">            <div>                You have been logged out.            </div>        </c:if>        <p>        <label for="username">用户名</label>        <input type="text" id="username" name="username"/>        </p>        <p>        <label for="password">密码</label>        <input type="password" id="password" name="password"/>        </p>        <!-- if using RememberMeConfigurer make sure remember-me matches RememberMeConfigurer#rememberMeParameter -->        <p>        <label for="remember-me">Remember Me?</label>        <input type="checkbox" id="remember-me" name="remember-me"/>        </p>        <div>            <button type="submit" class="btn">登录</button>        </div>    </fieldset> </form>`

1.1.2我们也可以自定义错误和退出界面
我们可以再控制器里面通过判断错误信息和退出信息是否为null来判断是否登录错误或者退出了系统。

@RequestMapping(method = RequestMethod.GET, value="/login")        public String login(                @RequestParam(required=false) String error,                @RequestParam(required=false) String logout){            if(error!=null){                //有错误退出行会到登录界面                return "login";             }            else if(logout!=null){                return "logout";                    //自定义退出            }            return "login";         }

1.2 我们需要写一个WebSecurityConfig 类继承WebSecurityConfigurerAdapter 来进行相关的配置进行权限管理。(相当于xml的配置,只是我们用java类来实现)

@Configuration  //作为配置类@EnableWebSecurity  //开启支持websecurity@EnableGlobalMethodSecurity(securedEnabled=true,prePostEnabled=true) //开启全局支持 精细化业务层控制--prePostEnabled:开启springsecurity注解public class WebSecurityConfig extends WebSecurityConfigurerAdapter {    @Autowired    private UserDetailsService userDetailsService;    //自定义模拟的用户    /*@Bean    @Override    public UserDetailsService userDetailsService(){        InMemoryUserDetailsManager manager=new InMemoryUserDetailsManager();        manager.createUser(User.withUsername("uesr")                .password("123456")                .roles("ROLE").build()                );        manager.createUser(User.withUsername("admin")                .password("123456")                .roles("ADMIN").build()                );        return manager;    }*/    //权限和静态资源的配置 过滤器阶段    @Override    protected void configure(HttpSecurity http) throws Exception {        http.authorizeRequests()        .antMatchers("/assets/**").permitAll()//相当于把这些限制加入过滤器        .antMatchers("/login").permitAll()        //越具体越上面        .antMatchers("/admin/**").hasRole("ADMIN") //只有admin能访问这个路径        .antMatchers("/**").authenticated().and()  //都可以访问但是要登录        .formLogin().loginPage("/login").and()        .rememberMe().tokenValiditySeconds(24*3600) //保存的时间        .userDetailsService(userDetailsService);//开启remenberMe的支持    }    //把密码加密类加入容器    @Bean    public PasswordEncoder passwordEncoder() {        return new BCryptPasswordEncoder();    }}

1.2.1自定义MyUser类来构造带权限的用户

public class MyUser extends User {    /**     *      */    private static final long serialVersionUID = 1L;    //Collection<? extends GrantedAuthority> authorities 权限集    //带权限的uesr 根据不同的角色赋予权限    public MyUser(String username, String password, String... roles) {        super(username, password, getSimpleGrantedAuthorityies(roles));    }    public static List<GrantedAuthority> getSimpleGrantedAuthorityies(String []role){        List<GrantedAuthority> authorities=new ArrayList<>();        for (int i = 0; i < role.length; i++) {            authorities.add(new SimpleGrantedAuthority("ROLE_"+role[i]));        }        return authorities;    }}

1.2.2自定义UserDetailsServiceImp limplements UserDetailsService用来接收用户传入的用户名,根据用户名进行权限匹配。然后同构MyUser来构造权限。

    @Autowired    private PasswordEncoder passwordEncoder;    //接收页面的参数       // 当spring security需要用户详情时调用此方法,传入用户名    @Override    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {        System.out.println("--- loadUserByUsername: " + userName);        System.out.println("--- 123456: " + passwordEncoder.encode("123456"));        //省略步骤 从数据库拿密码根据userName 然后和自定义的        switch (userName) {        case "user": return new MyUser("user", "$2a$10$ptZpQuzYlGGld.sfrZIh.e/RanX0/Olnuv7YNgIS8MB8dhxyLqI8O", "ROLE");        case "ad8min": return new MyUser("admin", "$2a$10$ptZpQuzYlGGld.sfrZIh.e/RanX0/Olnuv7YNgIS8MB8dhxyLqI8O", "ADMIN");        case "hr": return new MyUser("hr", "$2a$10$ptZpQuzYlGGld.sfrZIh.e/RanX0/Olnuv7YNgIS8MB8dhxyLqI8O", "ADMIN","HR");        default: throw new UsernameNotFoundException(userName + "不存在");        }       }

1.3最后我们就可已根据用户所带的权限差异来对用户开放不同的资源。

<!--需要拥有ADMIN的权限才能访问  -->    <sec:authorize access="hasRole('ADMIN')">    <a href="${pageContext.request.contextPath}/admin/userlist">跳转到列表界面</a>    </sec:authorize>        <!--需要拥有HR的权限才能访问  -->    <sec:authorize access="hasRole('HR')">    <a href="${pageContext.request.contextPath}/employees">跳转到员工界面</a>    </sec:authorize>

1.4我们在进过滤的时候主要经过两方面
(1)springsecurity的过滤器帮我们进行过滤也就是在WebSecurityConfig 类进行的配置

//权限和静态资源的配置 过滤器阶段    @Override    protected void configure(HttpSecurity http) throws Exception {        http.authorizeRequests()        .antMatchers("/assets/**").permitAll()//相当于把这些限制加入过滤器        .antMatchers("/login").permitAll()        //越具体越上面        .antMatchers("/admin/**").hasRole("ADMIN") //只有admin能访问这个路径        .antMatchers("/**").authenticated().and()  //都可以访问但是要登录        .formLogin().loginPage("/login").and()        .rememberMe().tokenValiditySeconds(24*3600) //保存的时间        .userDetailsService(userDetailsService);//开启remenberMe的支持    }

(2)还一个就是在service接口进行的服务层过滤

public interface IHrService {//  @Secured("ROLE_HR")    //需要完全登录和HR权限才能访问 注:需要开启prePostEnabled=true的支持在我们自定义的WebSecurityConfig 类中。    @PreAuthorize("isFullyAuthenticated()&&hasRole('HR')")    List<Employee>findAll();}

1.5 springsecurity图解
这里写图片描述

原创粉丝点击