提交 af25f72a 编写于 作者: Z zen

增加一次性动态口令验证功能

上级 458d4854
......@@ -26,4 +26,5 @@ export class TimeBased extends BaseEntity {
sharedSecret!: String;
hexSharedSecret!: String;
rqCode!: String;
otp!: string;
}
......@@ -14,7 +14,7 @@
<nz-form-control [nzSm]="14" [nzXs]="36" [nzXl]="48" nzErrorTip="The input is not displayName!">
<input
nz-input
readonly
[disabled]="isDisabled"
[(ngModel)]="form.model.displayName"
[ngModelOptions]="{ standalone: true }"
name="displayName"
......@@ -28,7 +28,7 @@
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid username!">
<input
nz-input
readonly
[disabled]="isDisabled"
[(ngModel)]="form.model.username"
[ngModelOptions]="{ standalone: true }"
name="username"
......@@ -39,13 +39,13 @@
<nz-form-item>
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="digits">{{ 'mxk.timebased.digits' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid digits!">
<input nz-input readonly [(ngModel)]="form.model.digits" [ngModelOptions]="{ standalone: true }" name="digits" id="digits" />
<input nz-input [disabled]="isDisabled" [(ngModel)]="form.model.digits" [ngModelOptions]="{ standalone: true }" name="digits" id="digits" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="period">{{ 'mxk.timebased.period' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid period!">
<input nz-input readonly [(ngModel)]="form.model.period" [ngModelOptions]="{ standalone: true }" name="period" id="period" />
<input nz-input [disabled]="isDisabled" [(ngModel)]="form.model.period" [ngModelOptions]="{ standalone: true }" name="period" id="period" />
</nz-form-control>
</nz-form-item>
<nz-form-item>
......@@ -53,7 +53,7 @@
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid sharedSecret!">
<input
nz-input
readonly
[disabled]="isDisabled"
[(ngModel)]="form.model.sharedSecret"
[ngModelOptions]="{ standalone: true }"
name="sharedSecret"
......@@ -66,7 +66,7 @@
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid hexSharedSecret!">
<input
nz-input
readonly
[disabled]="isDisabled"
[(ngModel)]="form.model.hexSharedSecret"
[ngModelOptions]="{ standalone: true }"
name="hexSharedSecret"
......@@ -74,10 +74,24 @@
/>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label [nzSm]="6" [nzXs]="24" nzFor="one-timePassword">{{ 'mxk.timebased.one-timePassword' | i18n }}</nz-form-label>
<nz-form-control [nzSm]="14" [nzXs]="24" nzErrorTip="The input is not valid One-Time Password!">
<input
nz-input
[(ngModel)]="form.model.otp"
[ngModelOptions]="{ standalone: true }"
placeholder="请在生成后输入一次性密码用于验证"
name="oneTimePassword"
id="oneTimePassword"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item style="width: 100%">
<nz-form-control [nzOffset]="7" [nzSpan]="12">
<nz-form-control [nzOffset]="7" [nzSpan]="3">
<button nz-button nzType="primary" type="submit" [nzLoading]="form.submitting">{{ 'mxk.text.generate' | i18n }}</button>
</nz-form-control>
<button nz-button nzType="primary" (click)="verify($event,form.model.otp)">{{ 'mxk.text.verify' | i18n }}</button>
</nz-form-item>
</div>
</div>
......
......@@ -28,7 +28,7 @@ import { Console } from 'console';
@Component({
selector: 'app-timebased',
templateUrl: './timebased.component.html',
styleUrls: ['./timebased.component.less']
styleUrls: ['./timebased.component.less'],
})
export class TimebasedComponent implements OnInit {
form: {
......@@ -39,6 +39,8 @@ export class TimebasedComponent implements OnInit {
model: new TimeBased()
};
isDisabled = true;
formGroup: FormGroup = new FormGroup({});
constructor(
......@@ -87,4 +89,18 @@ export class TimebasedComponent implements OnInit {
this.cdr.detectChanges();
});
}
verify(e: MouseEvent, otp: string): void {
e.preventDefault();
this.timeBasedService.verify(otp).subscribe(res => {
if (res.code == 0) {
this.msg.success(`验证成功`);
} else {
this.msg.error('验证失败');
}
})
// this.timeBasedService.verify(otp)
}
protected readonly String = String;
}
......@@ -37,4 +37,8 @@ export class TimeBasedService extends BaseService<TimeBased> {
override update(body: any): Observable<Message<TimeBased>> {
return this.http.get<Message<TimeBased>>(`${this.server.urls.base}/timebased?generate=YES`);
}
verify(otp: string): Observable<Message<TimeBased>>{
return this.http.get<Message<TimeBased>>(`${this.server.urls.base}/verify?otp=` + otp);
}
}
......@@ -543,7 +543,8 @@
"period": "period",
"sharedSecret": "sharedSecret(BASE32)",
"hexSharedSecret": "sharedSecret( HEX )",
"rqCode": "RQCode"
"rqCode": "RQCode",
"one-timePassword": "One-Time Password"
},
"socialsproviders": {
"icon": "Icon",
......@@ -683,6 +684,7 @@
"close": "Close",
"submit": "Submit",
"generate": "Generate",
"verify": "Verify",
"upload": "Upload",
"save": "Save",
"year": "Year",
......
......@@ -529,7 +529,8 @@
"period": "周期",
"sharedSecret": "共享密钥(BASE32)",
"hexSharedSecret": "共享密钥( HEX )",
"rqCode": "二维码"
"rqCode": "二维码",
"one-timePassword": "一次性密码"
},
"socialsassociate": {
"icon": "图标",
......@@ -686,6 +687,7 @@
"close": "关闭",
"submit": "提交",
"generate": "生成",
"verify": "验证",
"upload": "上传",
"save": "保存",
"year": "年",
......
......@@ -529,7 +529,8 @@
"period": "週期",
"sharedSecret": "共享密鑰(BASE32)",
"hexSharedSecret": "共享密鑰( HEX )",
"rqCode": "二維碼"
"rqCode": "二維碼",
"one-timePassword": "一次性密碼"
},
"socialsassociate": {
"icon": "圖標",
......@@ -686,6 +687,7 @@
"close": "關閉",
"submit": "提交",
"generate": "生成",
"verify": "驗證",
"upload": "上傳",
"save": "保存",
"year": "年",
......
......@@ -30,6 +30,7 @@ import org.maxkey.entity.Message;
import org.maxkey.entity.UserInfo;
import org.maxkey.password.onetimepwd.algorithm.OtpKeyUriFormat;
import org.maxkey.password.onetimepwd.algorithm.OtpSecret;
import org.maxkey.password.onetimepwd.impl.TimeBasedOtpAuthn;
import org.maxkey.persistence.service.UserInfoService;
import org.maxkey.util.RQCodeUtils;
import org.slf4j.Logger;
......@@ -58,6 +59,9 @@ public class OneTimePasswordController {
@Autowired
OtpKeyUriFormat otpKeyUriFormat;
@Autowired
private TimeBasedOtpAuthn timeBasedOtpAuthn;
@RequestMapping(value = {"/timebased"})
@ResponseBody
public ResponseEntity<?> timebased(
......@@ -99,5 +103,18 @@ public class OneTimePasswordController {
}
}
@RequestMapping("/verify")
public ResponseEntity<?> verify(@RequestParam("otp") String otp, @CurrentUser UserInfo currentUser) {
// 从当前用户信息中获取共享密钥
String sharedSecret = PasswordReciprocal.getInstance().decoder(currentUser.getSharedSecret());
// 计算当前时间对应的动态密码
boolean validate = timeBasedOtpAuthn.validate(currentUser, otp);
if (validate) {
return new Message<>(0,"One-Time Password verification succeeded").buildResponse();
} else {
return new Message<>(2,"One-Time Password verification failed").buildResponse();
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册