澳门威利斯人_威利斯人娱乐「手机版」

来自 网络资讯 2019-05-05 08:12 的文章
当前位置: 澳门威利斯人 > 网络资讯 > 正文

威尼斯娱乐城SpringSecurity开发基于表单的认证,相

近日做了一个有关vue.js的小demo:

天性化用户认证流程

  • 自定义登入页面
  • 自定义登录成功拍卖
  • 自定义登入战败管理

Django使用会话和中间件将注脚系统挂接到请求对象。 那些提供了表示当前用户的每种请求的request.user属性。 假诺当前用户未有登入,则此属性将设置为AnonymousUser的一个实例,不然它将是User的一个实例。 您能够利用is_authenticated()来区分它们,如下所示:

  当用户登入时,使用景况保存vuex将用户的头像音讯囤积到store.state个中,这样不相同用户登入就能够议及展览示相应的头像。

自定义登6页面

事先大家利用SpringSecurity暗许配置的报到页面,如表单登陆依然HTTP BASIC登陆,这里大家想自定义登入页面。首先大家修改安全安顿:

@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{

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

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.formLogin()
            .loginPage("/login.html")
            .and()
            .authorizeRequests()
            .anyRequest()
            .authenticated();
    }
}

在configure方法中钦点了登入页面包车型地铁UTiggoL后病还要在项目标/src/main/resources/下建三个resources文件夹,这么些文件夹里面放的是体系的文本暗中同意放置的门路,在这一个文件夹目录下增加三个login.html登入页面:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
    <h2>标准登录页面</h2>
</body>
</html>

启航应用后,大家走访地址http://localhost://8080/user/1后页面展现:

威尼斯娱乐城 1

error.png

致使那么些错误的由来是:大家在促成BrowserSecurityConfig 类的不二秘籍中,设置了登入页面为login.html的同时也安装了身份认证,导致访问login.html页面(也是1次呼吁)的时候也举办身份验证,如此循环循环访问,错误提示重定向次数过多。为此大家修改代码如下:

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.formLogin()
            .loginPage("/login.html")
            .and()
            .authorizeRequests()
            .antMatchers("/login.html").permitAll()
            .anyRequest()
            .authenticated();
    }

添加的antMatchers("/login.html").permitAll()那句表示当呼吁url符合那些门路时不实行身份认证,修改后大家走访http://localhost://8080/user/1后默许就跳到了笔者们自身布署的login.html登陆页面了。
接下去咱们对自定义的登入页面举办修改:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登陆页面</title>
</head>
<body>
    <h2>标准登陆页面</h2>
    <h3>表单登录</h3>
    <form action="/authentication/form" method="post">
        <table>
            <tr>
                <td>用户名:</td>
                <td><input type="text" name="username"></td>
            </tr>
            <tr>
                <td>密码:</td>
                <td><input type="text" name="password"></td>
            </tr>
            <tr>
                <td colspan="2"><button type="submit">登录</button></td>
            </tr>
        </table>
    </form>
</body>
</html>

威尼斯娱乐城,表单的性子action="/authentication/form" method="post"是我们温馨定义的url。记得第三讲说过,表单登入的伸手在SpringSecurity中是由UsernamePasswordAuthenticationFilter过滤器来拍卖的,那几个过滤器类中:

    public UsernamePasswordAuthenticationFilter() {
        super(new AntPathRequestMatcher("/login", "POST"));
    }

可知过滤器只管理url是:/login的POST请求,而作者辈修改后的报到页面提交时url是/authentication/form,为此我们须要在布局类中告知SpringSecurity现在表单登陆的呼吁url是有点:

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.formLogin()
            .loginPage("/login.html")
            .loginProcessingUrl("/authentication/form")
            .and()
            .authorizeRequests()
            .antMatchers("/login.html").permitAll()
            .anyRequest()
            .authenticated();
    }

loginProcessingUrl("/authentication/form")那句代码正是设置签到请求的url路径。
修改后大家重启应用,访问http://localhost://8080/user/1后暗许跳出我们设置的登6页面:

威尼斯娱乐城 2

image.png

填写正确的账号和密码后交付报错,如下:

威尼斯娱乐城 3

error.png

那是由SpringSecurity默许的跨站伪造防护导致的,此处我们修改设置如下:

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.formLogin()
            .loginPage("/login.html")
            .loginProcessingUrl("/authentication/form")
            .and()
            .authorizeRequests()
            .antMatchers("/login.html").permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .csrf().disable();
    }

修改后大家重新登入,那是表单登入页面填写准确的账号和密码后先后能访问到restful api了。
修改后大家今后的情事是当大家在浏览器发起一个呼吁访问http://localhost://8080/user/1的时候,
首先跳转到登6页面提醒我们登6。但假使大家想拜会url中末尾带html的,如http://localhost://8080/index.html的时候回来登陆页面,而只要访问http://localhost://8080/user/1的时候回来错误码,为此大家须要新建二个自定义的调整器来对以html结尾的伸手和非html结尾的伸手实行区分,我们在调节器的方法中判定是还是不是是html结尾的乞请引发的跳转,假若是则赶回登陆页面,假如不是则赶回40一状态码和错误消息。
上面大家新建三个调整器:

@RestController
public class BrowserSecurityController {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private RequestCache requestCache = new HttpSessionRequestCache();
    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
    @Autowired
    private SecurityProperties securityProperties;
    /**
     * 当需要身份认证时跳转到这里
     * @param request
     * @param response
     * @return
     * @throws IOException 
     */
    @RequestMapping("/authentication/require")
    @ResponseStatus(code = HttpStatus.UNAUTHORIZED)
    public SimpleResponse requireAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException{

        SavedRequest savedRequest = requestCache.getRequest(request, response);

        if(savedRequest != null){
            String target = savedRequest.getRedirectUrl();
            logger.info("引发跳转的请求是:" target);
            if(StringUtils.endsWithIgnoreCase(target, ".html")){
                redirectStrategy.sendRedirect(request, response, securityProperties.getBrowser().getLoginPage());
            }

        }
        return new SimpleResponse("访问的服务需要身份认证,请引导用户到登录页面");
    }
}

当呼吁url符合“/authentication/require”的路径时访问上述调控器的requireAuthentication方法,那几个艺术通过RequestCache对象和SavedRequest对象获得保存在缓存中的请求url,借使请求url的后缀为.html,则页面重定向到securityProperties.getBrowser().getLoginPage()的重返值;不然再次回到状态码HttpStatus.UNAUTHOGL450IZED,即40一,并且提醒“访问的劳务须求身份评释,请指点用户到登⑥页面”。注:
SimpleResponse类用于封装再次回到音信,使得以json格式重回,上边是其1SimpleResponse类的兑现:

public class SimpleResponse {
    public SimpleResponse(Object content){
        this.content = content;
    }
    private Object content;
    public Object getContent() {
        return content;
    }
    public void setContent(Object content) {
        this.content = content;
    }
}

那securityProperties.getBrowser().getLoginPage()具体是何许内容呢?
是这般的,我们将以.html为最后的伸手对应的跳转页面配置到了品种的性质文件application.properties文件中:

spring.security.browser.loginPage=/demo-signin.html

大家将以此自身配的品质分成两层,一层是spring.security,另壹层是spring.security下的browser。为了获取那一个天性,编写类SecurityProperties获取前缀是spring.security的本性

@ConfigurationProperties(prefix = "spring.security")
public class SecurityProperties {
    private BrowserProperties browser = new BrowserProperties();
    public BrowserProperties getBrowser() {
        return browser;
    }
    public void setBrowser(BrowserProperties browser) {
        this.browser = browser;
    }   
}

@ConfigurationProperties(prefix = "spring.security")注排毒示读取前缀是“spring.security”的习性。
本条SecurityProperties 类中又有一个变量BrowserProperties browser保存属性文件中配的第多少个字段browser的值,BrowserProperties对象的性质loginPage保存了第三个字段loginPage的值。上边是BrowserProperties类的切切实实落实:

public class BrowserProperties {
        private String loginPage;
    public String getLoginPage() {
        return loginPage;
    }
    public void setLoginPage(String loginPage) {
        this.loginPage = loginPage;
    }   
}

为使SecurityProperties这么些读取属性文件的类生效,供给再加二个配置类;

@Configuration
@EnableConfigurationProperties(SecurityProperties.class)
public class SecurityCoreConfig {
}

通过以上配置来使能获得属性配置的类生效。

最后我们修改登入行为:

@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired 
    SecurityProperties securityProperties;

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

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.formLogin()
            .loginPage("/authentication/require") //跳转的登录页
            .loginProcessingUrl("/authentication/form") //登录时的请求
            .and()
            .authorizeRequests()
            .antMatchers("/authentication/require",
                    securityProperties.getBrowser().getLoginPage()).permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .csrf().disable();
    }
}

运营应用后,当我们走访访问http://localhost:8080/user/1的时候由于未有引导教导登陆音讯,跳转到大家设置的”/authentication/require“路线下,那么些路子由大家刚安装的调节器来拍卖,末尾未有html新闻,所以回来的40一,并且提醒”访问的服务必要身份验证,请携带用户到登6页面“,并且url跳转到/authentication/require。即使访问http://localhost:8080/index.html的时候,则跳转到securityProperties.getBrowser().getLoginPage()点名的demo-signin.html页面上。demo-signin.html代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
    <h2>demo 登录页</h2>
</body>
</html>
if request.user.is_authenticated():
    # Do something for authenticated users.
else:
    # Do something for anonymous users.

实际贯彻格局:

自定义登十分之六功页面

当大家访问http://localhost:8080/user/1的时候先会跳到表单登6页,填写完账号密码登录成功后,会暗中同意跳转到/user/一请求对应的调节器上,这一步是SpringSecurity默许的管理类来管理的,假诺大家想登入成功后不实行默许的操作,而是落成我们须要的操作,就要询问一下接下去的源委。
自定义登五分三功页面必要贯彻AuthenticationSuccessHandler接口:

@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        //Authentication接口封装认证信息

        logger.info("登录成功");

        response.setContentType("application/json;charset=UTF-8");

        //将authentication认证信息转换为json格式的字符串写到response里面去
        response.getWriter().write(objectMapper.writeValueAsString(authentication));
    }
}

笔者们在接口的AuthenticationSuccessHandler方法上将认证消息放到response音信中。
别的我们要使用这几个自定义的登入成功拍卖类,而不是行使暗中同意的管理人,要求修改登入行为配置类:

@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired 
    SecurityProperties securityProperties;

    @Autowired
    private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

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

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.formLogin()
            .loginPage("/authentication/require") //跳转的登录页
            .loginProcessingUrl("/authentication/form") //登录时的请求
            .successHandler(myAuthenticationSuccessHandler) //表单登录成功时使用我们自己写的处理类
            .and()
            .authorizeRequests()
            .antMatchers("/authentication/require",
                    securityProperties.getBrowser().getLoginPage()).permitAll()
            .anyRequest()
            .authenticated()
            .and()
            .csrf().disable();
    }
}

透过引进MyAuthenticationSuccessHandler对象,并选用successHandler方法将其设置为记名成功的管理类。
如此起步应用后,表单登6填写完账号密码登入成功后,页面呈现我们塞到response中的认证音讯:

威尼斯娱乐城 4

pageinfo.png

威尼斯娱乐城 5

network.png

内部authenticated=true表示已经通过身份验证,authorities:admin等象征用户的权限是admin,credentials表示密码,一般springsecurity做了管理,不会再次来到到前台,所感到空,最主要的是printcipal中的内容,里面有我们以前在UserDetail类中设置的八个布尔值等音信。

何以登6用户

要从视图登入用户,请使用login()。 它须要二个HttpRequest对象和2个User对象。 login()使用Django的对话框架将用户的ID保存在对话中。 请注意,无名氏会话期间的其余数据集都将要用户登入后保留在对话中。此示例呈现怎么运用authenticate()和login():

from django.contrib.auth import authenticate, login

def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(username=username, password=password)
    if user is not None:
        if user.is_active:
            login(request, user)
            # Redirect to a success page.
        else:
            # Return a 'disabled account' error message
    else:
        # Return an 'invalid login' error message.

首先调用authenticate()首先,当您手动登入用户时,必须在调用login()以前调用authenticate()。 authenticate()在用户身上设置2个性能,提出哪个认证后端成功验证了该用户,并且此新闻在报到进程中稍后需求。 假使您尝试直接登入从数据库检索到的用户对象,则会掀起错误。

  在组件的乘除属性当中通过 this.$store.getters.userImg 获取当前用户的头像,然后用require引进图片,最终 return userImage 就能够。

自定义登入退步管理

相应的,登入失败的管理要促成的接口是

@Component
public class MyAuthenticationFailHandler implements AuthenticationFailureHandler {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException exception) throws IOException, ServletException {

        logger.info("登陆失败");
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(objectMapper.writeValueAsString(exception));
    }
}

贯彻情势中第七个法子不是表明音信而是登入失利的丰硕对象,我们选中AuthenticationException,然后右键选取open hierarchy查看类的承继图:

威尼斯娱乐城 6

image.png

由上海体育场合能够发掘,这一个可怜承接了累累任何越发,如UsernameNotFoundException卓殊(请求中未有用户名和密码),BadCredentialsException万分(账号密码错误)。
在onAuthenticationFailure管理方法中我们将错误音信重临,运行应用后,假如输入错误的账号密码后登录,页面呈现如下:

威尼斯娱乐城 7

image.png

打字与印刷出来的都是漏洞分外多的客栈消息。

什么登6用户

要注销通过login()登入的用户,请在您的视图中采纳logout()。 它必要八个HttpRequest对象并且没有重临值。 例:

from django.contrib.auth import logout

def logout_view(request):
    logout(request)
    # Redirect to a success page.

请留意,假使用户未登录,logout()不会掀起其余错误。当您调用logout()时,当前呼吁的对话数据将被透顶清除。 全部现成数量都将被剔除。 那是为了防范其旁人使用同3个Web浏览器登入并访问先前用户的对话数据。

借令你想把其它东西放到注销后迅就能够用的对话中,那么在调用logout()之后试行该操作。

本文由澳门威利斯人发布于网络资讯,转载请注明出处:威尼斯娱乐城SpringSecurity开发基于表单的认证,相

关键词: 澳门威利斯人 日记本 java jvm Django学习