SpringSecurity简单实现

pom依赖
<?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.4.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.power.grid</groupId>
    <artifactId>stateGrid</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>stateGrid</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-core</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- mybatisPlus 核心库 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.1</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>

    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
创建springboot项目时引入security,jdbc,mysql,web, mybatis, mybatis-plus,mysql dirver;创建好对应的权限控制表的实体类,实现UserDetails接口重写里边的方法
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
    return null;
}

//账户是否过期,过期无法验证
@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接口继承UserDetailsService
public interface WdpUserService extends UserDetailsService {
}
创建UserServiceImpl实现类实现UserService接口,重写UserDetails方法
@Service
public class WdpUserServiceImpl implements WdpUserService {

    @Autowired
    private WdpUserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserTable user = userMapper.findUserByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("用户名或密码错误");
        }else {
            user.setLogintime((int) (System.currentTimeMillis() / 1000));
            userMapper.saveLoginTime(user.getLogintime(),user.getId());
            return user;
        }

    }
}
然后写dao层、xml查询用户的sql逻辑就完成了,最后加上SecurityConfig配置类
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/js/**", "/css/**", "/images/**","/upload/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                /*.antMatchers("/admin/**").hasRole("admin")
                .antMatchers("/user/**").hasAnyRole("admin", "user")*/
                .antMatchers("/doLogin").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/doLogin")
                .successHandler((req, resp, authentication) -> {
                    Object principal = authentication.getPrincipal();
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                    request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, authentication);
                    String resStr = new ObjectMapper().writeValueAsString(principal);
                    WdpUserTable user = JSON.parseObject(resStr,WdpUserTable.class);
                    Map<String,Object> map = new HashMap<>();
                    map.put("id",user.getId());
                    map.put("loginname",user.getLoginname());
                    map.put("username",user.getUsername());
                    map.put("function",user.getFunction());
                    map.put("JSESSIONID",request.getSession().getId());
                    Result result = Result.ofSuccess(map);
                    out.write(JSON.toJSONString(result));
                    out.flush();
                    out.close();
                })
                .failureHandler((req, resp, e) -> {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    Result result = Result.ofFail(404,"用户名或密码错误");
                    out.write(JSON.toJSONString(result));
                    out.flush();
                    out.close();
                })
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler((req, resp, authentication) -> {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("注销成功");
                    out.flush();
                    out.close();
                })
                .permitAll()
                .and()
                .csrf().disable().exceptionHandling()
                .authenticationEntryPoint((req, resp, authException) -> {
                            resp.setContentType("application/json;charset=utf-8");
                            PrintWriter out = resp.getWriter();
                            out.write("尚未登录,请先登录");
                            out.flush();
                            out.close();
                        }
                );
    }
}
注意:SpringSecurity实现继承了UserDetails,不能直接修改成前端想要的返回格式,它是没有controller的,访问控制都在配置类里,所以修改成前端想要的格式要在这里修改,out.write()才是框架返回给前端的内容;
		String resStr = new ObjectMapper().writeValueAsString(principal);
		WdpUserTable user = JSON.parseObject(resStr,WdpUserTable.class);
		Map<String,Object> map = new HashMap<>();
		map.put("id",user.getId());
		map.put("loginname",user.getLoginname());
		map.put("username",user.getUsername());
		map.put("function",user.getFunction());
		map.put("JSESSIONID",request.getSession().getId());
		Result result = Result.ofSuccess(map);
		out.write(JSON.toJSONString(result));

SpringSecurity 的关键配置解析:

authentication 用户的认证对象
denyAll 结果始终为false
hasAnyRole(list of roles) 如果用户被授予了列表中任意的指定角色,结果为true
hasRole(role) 如果用户被授予了指定的角色,结果为true
hasIpAddress(IPAddress) 如果请求来自指定IP的话,结果为true
isAnonymous() 如果当前用户为匿名用户,结果为true
isAuthenticated() 如果当前用户进行了认证的话,结果为true
isFullyAuthenticated() 如果当前用户进行了完整认证的话(不是通过Remember-me功能进行的认证),结果为true
isRememberMe() 如果当前用户是通过Remember-me自动认证的,结果为true
permitAll() 结果始终为true
principal() 用户的principal对象

Spring Security是一个基于Spring框架的安全框架,可以轻松地实现各种安全策略,包括基于角色的访问控制、基于表达式的访问控制、单点登录、密码加密等。下面简单介绍一下如何使用Spring Security实现权限管理。 1. 添加Spring Security依赖 在Maven项目中,可以在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>5.5.0</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>5.5.0</version> </dependency> ``` 2. 配置Spring Security 可以在项目的配置文件中增加以下配置: ```xml <security:authentication-manager> <security:authentication-provider> <security:user-service> <security:user name="user" password="{noop}password" authorities="ROLE_USER"/> <security:user name="admin" password="{noop}password" authorities="ROLE_ADMIN"/> </security:user-service> </security:authentication-provider> </security:authentication-manager> <security:http> <security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" /> <security:form-login /> </security:http> ``` 上面的配置文件中,定义了两个用户,一个是普通用户,一个是管理员用户。同时,定义了访问/admin/**下的资源需要具有ROLE_ADMIN角色。配置完成后,所有的请求都会被Spring Security拦截,如果用户未登录或没有对应的权限,会被重定向到登录页面。 3. 使用Spring Security提供的API 在Java代码中,可以使用Spring Security提供的API来实现权限管理。例如,在Controller中可以使用@PreAuthorize注解来限制方法的访问权限: ```java @GetMapping("/admin") @PreAuthorize("hasRole('ROLE_ADMIN')") public String adminPage() { return "admin"; } ``` 上面的代码中,限制了访问/admin的页面必须具有ROLE_ADMIN角色。 通过以上步骤,可以使用Spring Security轻松地实现权限管理。需要注意的是,在实际项目中,需要根据具体的业务需求和安全策略进行配置和实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值