springboot整合springsecurity

2024-06-19 15:11:25 浏览数 (2)

springboot整合springsecurity

SpringSecurity

准备工作

引入依赖
代码语言:javascript复制
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
service层
代码语言:javascript复制
package com.xiaow.service;

import com.xiaow.entity.PermissionEntity;
import com.xiaow.entity.UserEntity;
import com.xiaow.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName MemberUserDetailsService
 * @Author xiaow
 * @Version V1.0
 **/
@Component
@Slf4j
public class MemberUserDetailsService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    /**
     * loadUserByUserName
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1.根据该用户名称查询在数据库中是否存在
        UserEntity userEntity = userMapper.findByUsername(username);
        if (userEntity == null) {
            return null;
        }
        // 2.查询对应的用户权限
        List<PermissionEntity> listPermission = userMapper.findPermissionByUsername(username);
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        listPermission.forEach(user -> {
            authorities.add(new SimpleGrantedAuthority(user.getPermTag()));
        });
        // 3.将该权限添加到security
        userEntity.setAuthorities(authorities);
        return userEntity;
    }

    public static void main(String[] args) {
//        UserDetailsService userDetailsService = (username) -> {
//            return null;
//        };
    }
}

springsecurity-basic验证方式

这种方式弹出一个类似于alert弹出的框进行账户的登录

需要一个config类

代码语言:javascript复制
package com.cyb.mobile.config;

import lombok.NoArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;

@Component
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 新增security账户
     * */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("xiaow").password("123").authorities("/");
    }


    /**
     * 配置验证的方式
     * */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
               //配置认证方式
        http.authorizeRequests().antMatchers("/**")
                .fullyAuthenticated()
                .and()
                .httpBasic();      //配置为basic认证
    }

    @Bean
    public static NoOpPasswordEncoder noOpPasswordEncoder(){
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }
}

springsecurity-form表单模式

代码语言:javascript复制
package com.cyb.mobile.config;

import lombok.NoArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;

@Component
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 新增security账户
     * */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            .withUser("xiaow").password("123").authorities("/");
    }


    /**
     * 配置验证的方式
     * */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
               //配置认证方式
        http.authorizeRequests().antMatchers("/**")
                .fullyAuthenticated()
                .and()
                .formLogin();      //配置为form认证              唯一修改的位置
    }

    @Bean
    public static NoOpPasswordEncoder noOpPasswordEncoder(){
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }
}

静态配置权限

使用角色来配置权限

代码语言:javascript复制
package com.cyb.mobile.config;

import lombok.NoArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.stereotype.Component;

@Component
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 新增security账户
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("xiaow").password("123").authorities("admin").and()
//                authorities("","","")多个角色以,分割
                .withUser("dw").password("123").authorities("student");
    }


    /**
     * 配置验证的方式
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置认证方式
        http.authorizeRequests()
//                配置端口权限
//                由角色来限定权限
                .antMatchers("/user/*").hasAnyAuthority("admin")
                .antMatchers("/blog/*").hasAnyAuthority("student")
                .antMatchers("/**")
                .fullyAuthenticated()
                .and()
                .formLogin();      //配置为basic认证
    }

    @Bean
    public static NoOpPasswordEncoder noOpPasswordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }
}

修改权限不足页面

进行配置错误页面

代码语言:javascript复制
@Configuration
public class WebServerConfig {
    @Bean
    public ConfigurableServletWebServerFactory webServerFactory(){
        TomcatServletWebServerFactory factory=new TomcatServletWebServerFactory();
        ErrorPage errorPage400=new ErrorPage(HttpStatus.BAD_REQUEST,"/error/400.html");
        ErrorPage errorPage401=new ErrorPage(HttpStatus.UNAUTHORIZED,"/error/401.html");
        ErrorPage errorPage403=new ErrorPage(HttpStatus.FORBIDDEN,"/error/403.html");
        ErrorPage errorPage404=new ErrorPage(HttpStatus.NOT_FOUND,"/error/404.html");
        ErrorPage errorPage415=new ErrorPage(HttpStatus.UNSUPPORTED_MEDIA_TYPE,"/error/415.html");
        ErrorPage errorPage500=new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,"/error/500.html");
        factory.addErrorPages(errorPage400,errorPage401,errorPage403,errorPage404,errorPage415,errorPage500);
        return factory;
    }
}

自定义登陆页面

代码语言:javascript复制
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置认证方式
        http.authorizeRequests()
//                配置端口权限
//                由角色来限定权限
                .antMatchers("/user/*").hasAnyAuthority("admin")
                .antMatchers("/blog/*").hasAnyAuthority("student")
                .antMatchers("/login.html").permitAll()   //允许所有人访问该页面
                .antMatchers("/**")
                .fullyAuthenticated()
                .and()
                .formLogin()
                .loginPage("/login.html").loginProcessingUrl("/login").permitAll()   //配置login为都可以访问
                .and().csrf().disable();
    }

动态为资源添加权限

代码语言:javascript复制
 @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置认证方式
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry expressionInterceptUrlRegistry =
                http.authorizeRequests();
        List<Permissions> list = permissionsService.list();
        list.forEach(p->{
            expressionInterceptUrlRegistry.antMatchers(p.getUrl()).hasAnyAuthority(p.getPermissions());
        });
        expressionInterceptUrlRegistry
                .antMatchers("/login.html").permitAll()//允许所有人访问该页面
                .antMatchers("/**").fullyAuthenticated().and()
                .formLogin()
                .loginPage("/login.html").loginProcessingUrl("/login").permitAll()   //配置login为都可以访问
                .and().csrf().disable();


    }
使用memberService来验证用户id和密码以及获取权限
代码语言:javascript复制
 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        // 设置用户账号信息和权限
//        auth.inMemoryAuthentication().withUser("mayikt_admin").password("mayikt")
//                .authorities("addMember", "delMember", "updateMember", "showMember");
//        // 如果mayikt_admin账户权限的情况 所有的接口都可以访问,如果mayikt_add 只能访问addMember
//        auth.inMemoryAuthentication().withUser("mayikt_add").password("mayikt")
//                .authorities("addMember");
        auth.userDetailsService(memberUserDetailsService).passwordEncoder(new PasswordEncoder() {
            /**
             * 对密码MD5
             * @param rawPassword
             * @return
             */
            @Override
            public String encode(CharSequence rawPassword) {
                return MD5Util.encode((String) rawPassword);
            }

            /**
             * rawPassword 用户输入的密码
             * encodedPassword 数据库DB的密码
             * @param rawPassword
             * @param encodedPassword
             * @return
             */
            public boolean matches(CharSequence rawPassword, String encodedPassword) {
                String rawPass = MD5Util.encode((String) rawPassword);
                boolean result = rawPass.equals(encodedPassword);
                return result;
            }
        });
    }
配置动态设置资源权限
代码语言:javascript复制
 protected void configure(HttpSecurity http) throws Exception {

        List<PermissionEntity> allPermission = permissionMapper.findAllPermission();
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry
                expressionInterceptUrlRegistry = http.authorizeRequests();
        allPermission.forEach((permission) -> {
            /**
             * 动态添加资源的访问权限
             */
            expressionInterceptUrlRegistry.antMatchers(permission.getUrl()).
                    hasAnyAuthority(permission.getPermTag());

        });
        expressionInterceptUrlRegistry.antMatchers("/login").permitAll()
                .antMatchers("/**").fullyAuthenticated()
                .and().formLogin().loginPage("/login").and().csrf().disable();

    }

0 人点赞