[make it easy] Web App Login Control & Authority Control

# Start
In web applications, it is common to control whether or not screen operations are possible based on login status and user privileges. In the case of an internal web application, the users are all good people, so you don't have to worry too much about the strictness of the controls, but if it is for external use or the Internet, you should be careful. The risk of minor hacking always exists on the Internet, such as directly typing a URL into a web screen without permission, or calling an unauthorized event directly with a developer tool.

efw uses a property setting method to prevent the above risks. I would like to introduce this article to you.。

# Skeleton Sample
The skeleton sample consists of a login screen, menu screen, and master management screen. I would like to control whether or not the master management screen can be operated based on the privileges of the logged-in user.

## Screen Image
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476221/8c4522a5-6725-3670-8b16-3235f4986dc2.png)

## Folder Structure
Lists the elements involved in privilege control. Images and CSS that do not require restrictions are excluded.
```
skeletonSample
│  error.jsp　　　　　　　　　エラー画面
│  head.jsp　　　　　　　　　 ヘッダ部品
│  headbeforelogining.jsp　　ヘッダ部品（ログイン前画面向け）
│  headwithoutmenu.jsp　　　 ヘッダ部品（メニューリンク無し画面向け）
│  LG01.jsp　　　　　　　　　 ログイン画面
│  LG02.jsp　　　　　　　　　 メニュー画面
│  LG03.jsp　　　　　　　　　 パスワード忘れ画面
│  LG04.jsp　　　　　　　　　 パスワード変更画面
│  MST01.jsp　　　　　　　　  ユーザマスタ画面
│  MST01_inputdialog.jsp　　 ユーザ登録サブ画面（部品取り扱い）
│  MST01_uploaddialog.jsp　　アップロードサブ画面（部品取り扱い）
│  paging.jsp　　　　　　　　 ページング部品
│  
└─WEB-INF
    │  
    ├─classes
    │      efw.properties
    │      
    └─efw
        └─event
                global.js
                head_logout.js　　ログアウトイベント
                LG01_clear.js
                LG01_cookie.js
                LG01_submit.js
                LG02_goto.js
                LG03_chgPwd.js
                LG03_init.js
                LG04_sndPwd.js
                MST01_add.js
                MST01_clear.js
                MST01_delete.js
                MST01_download.js
                MST01_edit.js
                MST01_init.js
                MST01_inputdialog_init.js
                MST01_inputdialog_save.js
                MST01_search.js
                MST01_upload.js
                MST01_uploaddialog_save.js
```
# Login Control
## Goal Description
- Login check is not required for the following pages and related events. In other words, you can operate it even if you are not logged in.
・Login page
・Forgot password page
・Password change page
・Error page
- The following pages and related events require login check. In other words, if you operate it while not logged in, an error will occur.
・Menu page
・User master page
- I don't want parts or sub-pages to be called independently.
- The logout event must be able to be called even when the user is not logged in.
For example, if you leave the menu screen open for a long time, it will time out. If you try to log out in this state and receive a "please log in" alert, it will feel strange.

## Property Settings
Configure the efw.properties file as follows to meet the above request.
```properties
efw.login.check = true
efw.login.key = USER_ID
efw.login.url = LG01.jsp
efw.outoflogin.url.pattern =[/](LG01|LG03|LG04).jsp
efw.outoflogin.eventid.pattern = LG01|LG03|LG04|head_logout
```
Translate the meaning of settings.
・Enable login control.
・The session item used for login control is USER_ID.
・The login screen is LG01.jsp.
・Screens that do not require login control are LG01.jsp, LG03.jsp, and LG04.jsp.
・Events containing the characters LG01, LG03, LG04, and head_logout do not require login control.

In the case of parts and sub-pages, they do not include the <efw:client> tag, so even if you forcefully call them from the browser, the event will not be executed, so there is no need to include them in the settings.

## Operation Explanation
- With the above settings, when you are not logged in (timed out) and operate a menu screen that is subject to login check, you will automatically be redirected to the login screen.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476221/34a3bd98-9685-180f-f770-c68e05407288.png)

- If an event subject to login check is executed in a non-login state (timeout state), the following error will be issued and the event will automatically transition to the login screen.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476221/ef72bca0-6d1a-b9d5-5e42-e6a684a05bf1.png)

- デベロッパーツールで軽いハッキングも同じくチェックされます。
以下のエビデンスは、未ログイン状態でログイン画面からユーザマスタ画面のイベントを呼び出すお試しです。イベント引数は基本的に画面とバインドしているから呼び出したらエラーが発生しますが、カスタマイズ引数の悪用でまたは引数なしの場合は呼び出せます。このとき、ログインチェック機能がガードしてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476221/1ce24bfe-40c8-e531-4f31-7f747c30c9d7.png)
 

# Authority Control
## Goal Description
Login users are further divided into two types: administrators and general users.
- Administrator
All screens and related events can be accessed.
- General user
User master screen and related events cannot be accessed.

## Property Settings
```properties
efw.auth.check = true
efw.auth.key = USER_ID
efw.system.error.url = error.jsp
efw.auth.cases = admin,user
admin.auth.pattern = ^admin.*$
admin.url.pattern = [/](LG02|MST01).jsp
admin.eventid.pattern = LG02|MST01
user.auth.pattern = ^((?!admin).)*$
user.url.pattern = [/](LG02).jsp
user.eventid.pattern = LG02
```
Translate the meaning of settings.
・Enable privilege control.
・The session item used for authority control is USER_ID.
・When a privilege control error occurs, the transition will be made to error.jsp on the system screen.
・There are two types of roles: administrator and general user.
・If the USER_ID is "admin##", it corresponds to the administrator role.
・Administrators can access the LG02.jsp and MST01.jsp screens.
・Administrators can access events containing the characters LG02 and MST01.
・If the USER_ID is not "admin##", it corresponds to a general user.
・General users can access the LG02.jsp screen.
・General users can access events containing the characters LG02.
It would be best to make the "User Management" button on the menu screen invisible to general users, but you will need a program to determine the role and control whether the button can be displayed. Please do this in the program on the menu screen, not in the property file settings.

LG01.jsp, LG03.jsp, LG04.jsp, error.jsp and related events do not require login and are not subject to permission control. In other words, it is a screen that anyone can see.

## Operation Explanation
- If general users try to connect a URL that is prohibited from viewing in the URL field, they will be redirected to a system error screen. And it doesn't explain why. *No need to be kind to hackers.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476221/d1675a72-2b05-e4a5-c461-57a56b69a348.png)

- When executing a prohibited event from the developer tools, an unexpected error message will be displayed. When you close the error message, you will be redirected to the system error page.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476221/9cd9519b-e3c0-6389-1f65-44232f249995.png)

For the system, it is common for a button to become inactive if it is prohibited to operate. In other words, normal operations should prevent you from going to prohibited screens and events. And permission control errors are only the reason for hacking. It is correct to give a system error.

# Environment
The skeleton sample uses DB, email, and POI.
Please read the previous article for information related to environment construction.

https://qiita.com/changkejun/items/d046d1804b4c996700e2

https://qiita.com/changkejun/items/26fe53af470ee1a96b05

https://qiita.com/changkejun/items/5f6c5b234dc1322ec859


The skeletonSample.backup file located directly under the sample folder is a postgres backup file. You can use it by restoring it. If you want to use another database, please create the table by referring to the SQL below.
```SQL
CREATE TABLE "ユーザマスタ"
(
  "ユーザID" character varying(10) NOT NULL, -- ユーザID
  "パスワード" character varying(10), -- パスワード
  "ユーザ名" character varying(20), -- ユーザ名
  "メール" character varying(50), -- メール
  "コメント" character varying(200), -- コメント
  "初期化フラグ" integer, -- 初期化フラグ	 1：初期パスワードの場合　...
  "ロックフラグ" integer, -- ロックフラグ
  "パスワード更新日" date, -- パスワード更新日
  "作成日時" date, -- 作成日時
  "作成者" character varying(10), -- 作成者
  "更新日時" date, -- 更新日時
  "更新者" character varying(10), -- 更新者
  CONSTRAINT "ユーザマスタ_PKC" PRIMARY KEY ("ユーザID")
);
```

You can download this sample from here.

https://github.com/efwGrp/qittaSamples