ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【无标题】

2022-03-06 12:01:30  阅读:126  来源: 互联网

标签:return String void request 无标题 Override public


提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、Spring Security是什么?

Spring Security是一个专注于为Java应用提供限权控制的框架吗,有以下优点:
1.对身份认证和授权提供全面的、可扩展的支持。
2.防止各种攻击,如会话固定攻击、点击劫持、csrf攻击等
3.支持与Servlet API、Spring MVC等Web技术集成
有关限权控制的核心主要有两点,认证和授权。认证大概意思就是,该用户是否登录,登录凭证是否过期等,认证后的用户才能进入系统。授权就是该用户有什么限权,例如是否有管理员限权。

二、使用步骤

1.引入依赖

代码如下(示例):

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

在SpringBoot中父pom已经声明了Spring Security的版本,建议使用默认版本

2.让用户对象实现UserDetails接口,实现以下方法

1.boolean isAccountNonExpired();// true: 账号未过期
2.boolean isAccountNonLocked();// true: 账号未锁定
3.boolean isCredentialsNonExpired();// true: 凭证未过期
4.boolean isEnabled();// true: 账号可用
5.Collection<? extends GrantedAuthority> getAuthorities();// 权限设置
代码如下:

public class User implements UserDetails {

    private int id;
    private String username;
    private String password;
    private String salt;
    private String email;
    private int type;
    private int status;
    private String activationCode;
    private String headerUrl;
    private Date createTime;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", salt='" + salt + '\'' +
                ", email='" + email + '\'' +
                ", type=" + type +
                ", status=" + status +
                ", activationCode='" + activationCode + '\'' +
                ", headerUrl='" + headerUrl + '\'' +
                ", createTime=" + createTime +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getActivationCode() {
        return activationCode;
    }

    public void setActivationCode(String activationCode) {
        this.activationCode = activationCode;
    }

    public String getHeaderUrl() {
        return headerUrl;
    }

    public void setHeaderUrl(String headerUrl) {
        this.headerUrl = headerUrl;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    // true: 账号未过期
    @Override
    public boolean isAccountNonExpired() {
        return false;
    }

    // true: 账号未锁定
    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    // true: 凭证未过期
    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    // true: 账号可用
    @Override
    public boolean isEnabled() {
        return true;
    }

    // 权限设置,限权根据自己表中定义的字段灵活修改,下面代码表示,在用户表中,type字段,1代表管理员,其他字段代表普通用户,根据对应的数字返回对应限权的字符串。
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> list = new ArrayList<>();
        list.add(new GrantedAuthority() {
            @Override
            public String getAuthority() {
                switch (type){
                    case 1:
                        return "ADMIN";
                    default:
                        return "USER";
                }
            }
        });
        return list;
    }

}

3.让提供用户登录服务的UserService,实现UserDetailsService接口

该接口中主要实现loadUserByUsername(String s)方法,该方法会更据用户输入的用户名搜索得到用户对象。
代码如下:

public class UserService implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;


    public User findUserByName(String username){
        return userMapper.selectByName(username );
    }

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        return this.findUserByName(s);
    }
}

4.对Spring Security配置类进行配置,实现灵活的限权控制

代码如下:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 忽略静态资源的访问
        web.ignoring().antMatchers("/resources/**");
    }

    // AuthenticationManager: 认证的核心接口
    // AuthenticationManagerBuilder: 用于构建AuthenticationManager的核心工具
    // providerManager: AuthenticationManager默认实现类
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        // 内置的认证规则
        //auth.userDetailsService(userService).passwordEncoder(new Pbkdf2PasswordEncoder("12345"));

        // 自定义认证规则
        // AuthenticationProvider: providerManager持有一组AuthenticationProvider,每一个AuthenticationProvider负责一种认证.
        // 委托模式: providerManager将认委托给AuthenticationProvider.
        auth.authenticationProvider(new AuthenticationProvider() {
            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                // authentication持有请求用户输入的账号密码
                String username = authentication.getName();
                String password = (String)authentication.getCredentials();

                // 调用service方法,对用户输入进行判断
                User user = userService.findUserByName(username);
                if (user == null) {
                    throw new UsernameNotFoundException("账号不存在!");
                }

                password = CommunityUtil.md5(password + user.getSalt());
                if (!user.getPassword().equals(password)) {
                    throw new BadCredentialsException("密码不正确");
                }
                // 通过验证,返回对象
                // principal: 主要信息; credenLials: 证书; Authorities: 限权;
                return new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
            }

            // 当前的AuthenticationProvider支持哪种类型的认证
            @Override
            public boolean supports(Class<?> aClass) {
                // UsernamePasswordAuthenticationToken: Authentication的常用的实现类
                return UsernamePasswordAuthenticationToken.class.equals(aClass);
            }
        });

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 登录相关配置(哪个页面是登录页面?处理登陆处理的路径是哪个?成功以后怎么处理?成功时怎么处理?)
        http.formLogin()
                .loginPage("loginpage")
                .loginProcessingUrl("lofin")
                .successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                        response.sendRedirect(request.getContextPath() + "index");
                    }
                })
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
                        request.setAttribute("error", e.getMessage());
                        request.getRequestDispatcher("/loginpage").forward(request, response);
                    }
                });

        // 退出相关配置(退出路径?退出成功怎么办?退出失败怎么办?)
        http.logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
                        response.sendRedirect(request.getContextPath() + "index");
                    }
                });

        // 授权配置(什么限权能访问什么页面?没有限权访问失败了怎么办?)
        http.authorizeRequests()
                .antMatchers("/letter").hasAnyAuthority("USER", "ADMIN")
                .antMatchers("admin").hasAnyAuthority("ADMIN")
                .and().exceptionHandling().accessDeniedPage("/denied");

        // 增加Filter,处理验证码
        http.addFilterBefore(new Filter() {
            @Override
            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
                HttpServletRequest request = (HttpServletRequest) servletRequest;
                HttpServletResponse response = (HttpServletResponse) servletResponse;

                if (request.getServletPath().equals("/login")) {
                    String verifyCode = request.getParameter("verifyCode");
                    if (verifyCode == null || verifyCode.equalsIgnoreCase("1234")) {
                        request.setAttribute("error", "验证码错误!");
                        request.getRequestDispatcher("/loginpage").forward(request, response);
                    }

                }

            }
        }, UsernamePasswordAuthenticationFilter.class);

        // 记住我
        http.rememberMe()
                .tokenRepository(new InMemoryTokenRepositoryImpl())
                .tokenValiditySeconds(3600 * 24)
                .userDetailsService(userService);

    }



}

总结

本文仅仅简单介绍了Spring Security的使用,Spring Security的底层是由16个过滤器组成,理解该过滤器极有利于我们对Java应用的理解。

标签:return,String,void,request,无标题,Override,public
来源: https://blog.csdn.net/bythy/article/details/123307188

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有