SpringSecurity 0到1

SpringSecurity

1 springsecurity 依赖包

<!--   security-->
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!--   thymeleaf-->
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--   securitythymeleaf-->
<dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>

2 springsecurity config 配置

实现UserDetailsService

@Service
public class UserServiceImpl implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //根据username 查询数据库
        if (!"admin".equals(username)){
            throw new UsernameNotFoundException("用户名或密码错误");
        }
        //根据查询的对象比较密码
        String password = passwordEncoder.encode("123456");
        //返回用户对象
        return new User("admin",password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal,ROLE_abc,/toMain,/main.html,/insert,/select"));
    }
}

创建WebSecurityConfig 继承 WebSecurityConfigurerAdapter 配置信息

public class WebSecurityConfig extends WebSecurityConfigurerAdapter

实现configure(HttpSecurity http)

protected void configure(HttpSecurity http) throws Exception {
        //表单登录
        http.formLogin()
                //自定义登录页面
                .loginPage("/showLogin")
                //自定义登录逻辑
                .loginProcessingUrl("/login")
                //登录成功跳转页面 必须是POST请求
                .successForwardUrl("/toMain")
                //自定义成功跳转页面
//                .successHandler(new MyAuthenticationSuccessHandler("/toMain"))
                //登录失败
                .failureForwardUrl("/toError")
                //自定义失败跳转页面
//                .failureHandler(new MyAuthenticationFailureHandler("http://www.qq.com"))
                //自定义用户名密码
//                .usernameParameter("username")
//                .passwordParameter("password")
                ;

        //授权
        http.authorizeRequests()
                //放行页面  ant表达式 regex表达式
                .antMatchers("/showLogin","/error.html","/**/*.jpg").permitAll()
                //通过用户权限
//                .antMatchers("/main1.html").hasAnyAuthority("admin")
                //根据角色匹配,不能以ROLE_开头  严格区分大小写
//                .antMatchers("/main1.html").hasAnyRole("abc")
//                .antMatchers("/main1.html").hasIpAddress("基于IP地址控制")
//                .regexMatchers()
                //所有请求都必须认证登录
                //注解@方式
                .anyRequest().authenticated();
                    //自定义逻辑
//                .anyRequest().access("@myServiceImpl.hasPermission(request,authentication)");

        //自定义403
        http.exceptionHandling()
                .accessDeniedHandler(myAccessDeniedHandler);

        http.rememberMe()
                //自定义参数
//                .rememberMeParameter("")
                //失效时间
//                .tokenValiditySeconds()
                //自定义记住我实现
//                .rememberMeServices()
                .userDetailsService(userService).tokenRepository(persistentTokenRepository);

        //退出登录
        http.logout()
                .logoutUrl("/logout").logoutSuccessUrl("/login.html");

        //csrf 跨域
        //关闭csrf防护
//        http.csrf().disable();
    }

自动定义跳转页面

成功页
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private final String forwardUrl;


    public MyAuthenticationSuccessHandler(String forwardUrl) {
        this.forwardUrl = forwardUrl;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
//        System.out.println(authentication.getAuthorities());
//        System.out.println(authentication.getCredentials());
//        System.out.println(authentication.getDetails());
//        Object principal = authentication.getPrincipal();
        WebAuthenticationDetails webAuthenticationDetails = (WebAuthenticationDetails) authentication.getDetails();
        System.out.println(webAuthenticationDetails.getRemoteAddress());
        httpServletResponse.sendRedirect(forwardUrl);
    }
}
失败页
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {

    private final String forwardUrl;

    public MyAuthenticationFailureHandler(String forwardUrl) {
        this.forwardUrl = forwardUrl;
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
        httpServletResponse.sendRedirect(forwardUrl);
    }
}
403页
@Configuration
public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        httpServletResponse.setContentType("application/json;charset=utf-8");

        PrintWriter writer = httpServletResponse.getWriter();

        writer.write("{\"status\":\"403\",\"msg\":\"权限不足,请联系管理员\"}");
        writer.flush();
        writer.close();
    }
}
自定义控制访问逻辑
@Service
public class MyServiceImpl implements MyService{
    @Override
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        String uri = request.getRequestURI();
        Object principal = authentication.getPrincipal();
        if (principal instanceof UserDetails){
            UserDetails userDetails = (UserDetails) principal;
            Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();

            return authorities.contains(new SimpleGrantedAuthority(uri));
        }
        return false;
    }
}

springsecurity oauth2

1 依赖包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.zsecode</groupId>
    <artifactId>springSecurityOauth</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springSecurityOauth</name>
    <description>springSecurityOauth</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
<!--       依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>

<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-data-redis</artifactId>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>org.apache.commons</groupId>-->
<!--            <artifactId>commons-pool2</artifactId>-->
<!--        </dependency>-->


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2 pojo

user

public class User implements UserDetails {

    private String username;
    private String password;
    List<GrantedAuthority> authorities;

    public User() {
    }

    public User(String username, String password, List<GrantedAuthority> authorities) {
        this.username = username;
        this.password = password;
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return this.authorities;
    }

    @Override
    public String getPassword() {
        return this.password;
    }

    @Override
    public String getUsername() {
        return this.username;
    }

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

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

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

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

UserService

@Service
public class UserService implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return new User("admin",passwordEncoder.encode("123456"), AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }
}

SecurityConfig

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf()
                .disable()
                .authorizeRequests()
                .antMatchers("/oauth/**","/login/**","/logout/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll();
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

请添加图片描述

AuthorizationServer

@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserService userService;


    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired
    private TokenEnhancer tokenEnhancer;

//    @Autowired
//    private TokenStore tokenStore;


    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        //token增强链
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        List<TokenEnhancer> delegates = new ArrayList<>();
        delegates.add(tokenEnhancer);
        delegates.add(jwtAccessTokenConverter);
        tokenEnhancerChain.setTokenEnhancers(delegates);

        endpoints.userDetailsService(userService)
                .authenticationManager(authenticationManager)
                .tokenStore(tokenStore)
                .accessTokenConverter(jwtAccessTokenConverter)
                //token增强链
                .tokenEnhancer(tokenEnhancerChain);
//                .tokenStore(tokenStore);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                //clientID
                .withClient("admin")
                //client密码
                .secret(passwordEncoder.encode("123456"))
                //令牌失效时间
                .accessTokenValiditySeconds(36000)
                //重定向地址
                .redirectUris("http://www.baidu.com")
                //授权范围
                .scopes("all")
                //授权类型
                .authorizedGrantTypes("authorization_code","password","refresh_token");

    }
}

JwtTokenConfig

@Configuration
public class JwtTokenConfig {

    @Bean
    public TokenStore jwtTokenStore(){
        return new JwtTokenStore(jwtAccessTokenConverter());
    }


    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setSigningKey("xxxx");
        return jwtAccessTokenConverter;
    }


    @Bean
    public TokenEnhancer tokenEnhancer(){
        return new MyTokenEnhancer();
    }
}

MyTokenEnhancer


public class MyTokenEnhancer implements TokenEnhancer {
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {

        Map<String,Object> map = new HashMap<>();
        map.put("enhancer","enhancer info");
        ((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(map);
        return oAuth2AccessToken;
    }
}

RedisConfig

@Configuration
public class RedisConfig {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    public TokenStore redisTokenStore(){
        return new RedisTokenStore(redisConnectionFactory);
    }
}

ResourceConfig

@Configuration
@EnableResourceServer
public class ResourceConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .requestMatchers().mvcMatchers("/user/**");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZSECode

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值