目次
登录
登录成功!${username}
ホームページ 类库下载 java类库 Spring Security を使用して、シンプルなログインと権限のロール制御を実装する

Spring Security を使用して、シンプルなログインと権限のロール制御を実装する

Oct 17, 2016 am 09:08 AM

まず、ログインに必要なものを考えます。最も単純なケースでは、ユーザー名とパスワードをデータベースと比較し、一致する場合は、個人ページに移動します。そうでない場合は、ログイン ページに戻り、ユーザー名を入力するよう求められます。とパスワードが間違っています。このプロセスには権限の役割も必要であり、セッション全体を通じて継続する必要があります。このアイデアでは、比較のためにデータベースのユーザー名とパスワードを Spring セキュリティに渡すだけでよく、その後はセキュリティに適切なジャンプを行わせ、セッション全体にわたってアクセス許可のロールとユーザー名を設定するのをセキュリティに任せます。実際、必要なのは正しいユーザー名とパスワードを入力し、セキュリティを設定することだけです。

ディレクトリ

準備

ログインページ

個人ページ

Spring Securityの設定を開始

1. Spring Securityを開始する

2. 権限を設定する

3. UserDetailServiceを書く

まずデータベーステーブルを準備する

わーい

追記: ここで注意すべきは、LEADER も MEMBER であるということです。このように、LEADER は後述するアプリケーション内での判断も行うことができます。

CREATE TABLE `user` (
  `username` varchar(255) NOT NULL,
  `password` char(255) NOT NULL,
  `roles` enum('MEMBER','MEMBER,LEADER','SUPER_ADMIN') NOT NULL DEFAULT 'MEMBER',
  PRIMARY KEY (`username`),
  KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ログイン後にコピー

個人ページ

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
    <title>登录</title>
</head>
<body>
<div >
    
    <sf:form action="${pageContext.request.contextPath}/log" method="POST" commandName="user">     <!-- spring表单标签,用于模型绑定和自动添加隐藏的CSRF token标签 -->
        <h1 id="登录">登录</h1>
        <c:if test="${error==true}"><p style="color: red">错误的帐号或密码</p></c:if>      <!--  登陆失败会显示这句话 -->
        <c:if test="${logout==true}"><p >已退出登录</p></c:if>                    <!-- 退出登陆会显示这句话 -->
        <sf:input path="username" name="user.username"  placeholder="输入帐号" /><br />
        <sf:password path="password" name="user.password"  placeholder="输入密码" /><br />
        <input id="remember-me" name="remember-me" type="checkbox"/>                <!-- 是否记住我功能勾选框 -->
        <label for="remember-me">一周内记住我</label>
        <input type="submit" class="sumbit" value="提交" >
    </sf:form>
</div>
</body>
</html>
ログイン後にコピー

Spring Securityの設定を開始


Spring Securityを開始

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false"%>
<%@taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
    <title>欢迎你,<security:authentication property="principal.username" var="username"/>${username}</title>      <!--  登陆成功会显示名字,这里var保存用户名字到username变量,下面就可以通过EL获取 -->
</head>
<body>
<security:authorize access="isAuthenticated()"><h3 id="登录成功-username">登录成功!${username}</h3></security:authorize>  <!--  登陆成功会显示名字 -->

<security:authorize access="hasRole(&#39;MEMBER&#39;)">              <!--  MENBER角色就会显示 security:authorize标签里的内容-->
    <p>你是MENBER</p>
</security:authorize>

<security:authorize access="hasRole(&#39;LEADER&#39;)">
    <p>你是LEADER</p>
</security:authorize>


<sf:form id="logoutForm" action="${pageContext.request.contextPath}/logout" method="post">      <!--  登出按钮,注意这里是post,get是会登出失败的 -->
    <a href="#" onclick="document.getElementById(&#39;logoutForm&#39;).submit();">注销</a>
</sf:form>
</body>
</html>
ログイン後にコピー

AbstractSecurityWebApplicationInitializerを継承すると、Spring Securityは自動的に準備を行います。ここで@Order(2)は私のspringmvc(これも純粋なアノテーション構成)です。 Spring Security を起動するときにエラーが発生しました。それが何だったか忘れました。後でセキュリティを起動するためにこれを追加すると、@Order(2) を書かなくてもこの問題は回避できます。

2. 権限を設定します

@Order(2)public class WebSecurityAppInit extends AbstractSecurityWebApplicationInitializer{
}
ログイン後にコピー

3. UserDetailService を書き込みます

Spring Security がユーザー情報を取得するために提供するサービスは、主にユーザーを確認するための情報を備えたセキュリティを提供します ここでは、独自のニーズをカスタマイズできます ユーザーの情報を取得します。ユーザー名に従ってデータベースから取得し、その後の処理のためにセキュリティに引き渡します

@Configuration
@EnableWebSecurity
@ComponentScan("com.chuanzhi.workspace.service.impl.*")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{          

    @Autowired
    private UserDetailService userDetailService;                  //如果userDetailService没有扫描到就加上面的@ComponentScan

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                    .antMatchers("/me").hasAnyRole("MEMBER","SUPER_ADMIN")  //个人首页只允许拥有MENBER,SUPER_ADMIN角色的用户访问
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/").permitAll()                  //这里程序默认路径就是登陆页面,允许所有人进行登陆
                    .loginProcessingUrl("/log")                  //登陆提交的处理url
                    .failureForwardUrl("/?error=true")              //登陆失败进行转发,这里回到登陆页面,参数error可以告知登陆状态
                    .defaultSuccessUrl("/me")                    //登陆成功的url,这里去到个人首页
                    .and()
                .logout().logoutUrl("/logout").permitAll().logoutSuccessUrl("/?logout=true")    //按顺序,第一个是登出的url,security会拦截这个url进行处理,所以登出不需要我们实现,第二个是登出url,logout告知登陆状态
                    .and()
                .rememberMe()
                    .tokenValiditySeconds(604800)                //记住我功能,cookies有限期是一周
                    .rememberMeParameter("remember-me")              //登陆时是否激活记住我功能的参数名字,在登陆页面有展示
                    .rememberMeCookieName("workspace");            //cookies的名字,登陆后可以通过浏览器查看cookies名字
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailService);                //配置自定义userDetailService
    }
}
ログイン後にコピー

次回ログインページに入るときに、Remember me 機能が有効になっているときに個人のホームページに直接ジャンプしたい場合は、次のようにすることができます。このコントローラー コードを見てください

@Service(value = "userDetailService")
public class UserDetailService implements UserDetailsService {

    @Autowired
    private UserRepository repository;          

    public UserDetailService(UserRepository userRepository){
        this.repository = userRepository;              //用户仓库,这里不作说明了
    }

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User user = repository.findUserByUsername(username);
        if (user==null)
            throw new UsernameNotFoundException("找不到该账户信息!");          //抛出异常,会根据配置跳到登录失败页面

        List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();      //GrantedAuthority是security提供的权限类,

        getRoles(user,list);              //获取角色,放到list里面

        org.springframework.security.core.userdetails.User auth_user = new
                org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),list);      //返回包括权限角色的User给security
        return auth_user;
    }

    /**
     * 获取所属角色
     * @param user
     * @param list
     */
    public void getRoles(User user,List<GrantedAuthority> list){
        for (String role:user.getRoles().split(",")) {
            list.add(new SimpleGrantedAuthority("ROLE_"+role));          //权限如果前缀是ROLE_,security就会认为这是个角色信息,而不是权限,例如ROLE_MENBER就是MENBER角色,CAN_SEND就是CAN_SEND权限
        }
    }
}
ログイン後にコピー

結果表示:

Spring Security を使用して、シンプルなログインと権限のロール制御を実装する

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)