Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
reg-app
Regapp
Commits
14e9b179
Commit
14e9b179
authored
Jul 02, 2020
by
ls1947
Browse files
add token create for totp and yubico
parent
74946b43
Changes
5
Hide whitespace changes
Inline
Side-by-side
bwreg-service/src/main/java/edu/kit/scc/webreg/service/twofa/TwoFaService.java
View file @
14e9b179
...
...
@@ -18,4 +18,10 @@ public interface TwoFaService {
Boolean
hasActiveToken
(
Long
userId
)
throws
TwoFaException
;
LinotpSimpleResponse
deleteToken
(
Long
userId
,
String
serial
)
throws
TwoFaException
;
LinotpSimpleResponse
checkSpecificToken
(
Long
userId
,
String
serial
,
String
token
)
throws
TwoFaException
;
LinotpInitAuthenticatorTokenResponse
createYubicoToken
(
Long
userId
,
String
yubi
)
throws
TwoFaException
;
}
bwreg-service/src/main/java/edu/kit/scc/webreg/service/twofa/TwoFaServiceImpl.java
View file @
14e9b179
...
...
@@ -81,7 +81,17 @@ public class TwoFaServiceImpl implements TwoFaService {
LinotpConnection
linotpConnection
=
new
LinotpConnection
(
configMap
);
return
linotpConnection
.
checkToken
(
user
,
token
);
}
@Override
public
LinotpSimpleResponse
checkSpecificToken
(
Long
userId
,
String
serial
,
String
token
)
throws
TwoFaException
{
UserEntity
user
=
userDao
.
findById
(
userId
);
Map
<
String
,
String
>
configMap
=
configResolver
.
resolveConfig
(
user
);
LinotpConnection
linotpConnection
=
new
LinotpConnection
(
configMap
);
return
linotpConnection
.
checkSpecificToken
(
serial
,
token
);
}
@Override
public
LinotpInitAuthenticatorTokenResponse
createAuthenticatorToken
(
Long
userId
)
throws
TwoFaException
{
UserEntity
user
=
userDao
.
findById
(
userId
);
...
...
@@ -103,7 +113,25 @@ public class TwoFaServiceImpl implements TwoFaService {
throw
new
TwoFaException
(
"Token generation did not succeed!"
);
}
}
@Override
public
LinotpInitAuthenticatorTokenResponse
createYubicoToken
(
Long
userId
,
String
yubi
)
throws
TwoFaException
{
UserEntity
user
=
userDao
.
findById
(
userId
);
Map
<
String
,
String
>
configMap
=
configResolver
.
resolveConfig
(
user
);
LinotpConnection
linotpConnection
=
new
LinotpConnection
(
configMap
);
linotpConnection
.
requestAdminSession
();
LinotpInitAuthenticatorTokenResponse
response
=
linotpConnection
.
createYubicoToken
(
user
,
yubi
);
if
(
response
==
null
)
{
throw
new
TwoFaException
(
"Token generation did not succeed!"
);
}
return
response
;
}
@Override
public
LinotpSimpleResponse
disableToken
(
Long
userId
,
String
serial
)
throws
TwoFaException
{
UserEntity
user
=
userDao
.
findById
(
userId
);
...
...
@@ -127,4 +155,17 @@ public class TwoFaServiceImpl implements TwoFaService {
return
linotpConnection
.
enableToken
(
serial
);
}
@Override
public
LinotpSimpleResponse
deleteToken
(
Long
userId
,
String
serial
)
throws
TwoFaException
{
UserEntity
user
=
userDao
.
findById
(
userId
);
Map
<
String
,
String
>
configMap
=
configResolver
.
resolveConfig
(
user
);
LinotpConnection
linotpConnection
=
new
LinotpConnection
(
configMap
);
linotpConnection
.
requestAdminSession
();
return
linotpConnection
.
deleteToken
(
serial
);
}
}
bwreg-service/src/main/java/edu/kit/scc/webreg/service/twofa/linotp/LinotpConnection.java
View file @
14e9b179
...
...
@@ -86,8 +86,8 @@ public class LinotpConnection {
context
.
setAuthCache
(
authCache
);
config
=
RequestConfig
.
custom
()
.
setSocketTimeout
(
5
000
)
.
setConnectTimeout
(
5
000
)
.
setSocketTimeout
(
30
000
)
.
setConnectTimeout
(
30
000
)
.
build
();
httpClient
=
HttpClients
.
custom
().
setDefaultRequestConfig
(
config
).
build
();
}
...
...
@@ -125,6 +125,36 @@ public class LinotpConnection {
}
}
public
LinotpSimpleResponse
checkSpecificToken
(
String
serial
,
String
token
)
throws
TwoFaException
{
try
{
HttpPost
httpPost
=
new
HttpPost
(
configMap
.
get
(
"url"
)
+
"/validate/check_s"
);
List
<
NameValuePair
>
nvps
=
new
ArrayList
<
NameValuePair
>();
if
(
configMap
.
containsKey
(
"realm"
))
nvps
.
add
(
new
BasicNameValuePair
(
"realm"
,
configMap
.
get
(
"realm"
)));
nvps
.
add
(
new
BasicNameValuePair
(
"serial"
,
serial
));
nvps
.
add
(
new
BasicNameValuePair
(
"pass"
,
token
));
httpPost
.
setEntity
(
new
UrlEncodedFormEntity
(
nvps
));
CloseableHttpResponse
response
=
httpClient
.
execute
(
targetHost
,
httpPost
,
context
);
try
{
HttpEntity
entity
=
response
.
getEntity
();
String
responseString
=
EntityUtils
.
toString
(
entity
);
logger
.
trace
(
responseString
);
return
resultParser
.
parseSimpleResponse
(
responseString
);
}
finally
{
response
.
close
();
}
}
catch
(
ParseException
|
IOException
e
)
{
throw
new
TwoFaException
(
e
);
}
}
public
LinotpInitAuthenticatorTokenResponse
createAuthenticatorToken
(
UserEntity
user
)
throws
TwoFaException
{
try
{
HttpPost
httpPost
=
new
HttpPost
(
configMap
.
get
(
"url"
)
+
"/admin/init"
);
...
...
@@ -163,6 +193,41 @@ public class LinotpConnection {
}
}
public
LinotpInitAuthenticatorTokenResponse
createYubicoToken
(
UserEntity
user
,
String
yubi
)
throws
TwoFaException
{
try
{
HttpPost
httpPost
=
new
HttpPost
(
configMap
.
get
(
"url"
)
+
"/admin/init"
);
List
<
NameValuePair
>
nvps
=
new
ArrayList
<
NameValuePair
>();
nvps
.
add
(
new
BasicNameValuePair
(
"session"
,
adminSession
));
nvps
.
add
(
new
BasicNameValuePair
(
"type"
,
"yubico"
));
nvps
.
add
(
new
BasicNameValuePair
(
"yubico.tokenid"
,
yubi
));
nvps
.
add
(
new
BasicNameValuePair
(
"description"
,
"This is a description"
));
if
(
configMap
.
containsKey
(
"userId"
))
nvps
.
add
(
new
BasicNameValuePair
(
"user"
,
configMap
.
get
(
"userId"
)));
else
nvps
.
add
(
new
BasicNameValuePair
(
"user"
,
user
.
getEppn
()));
if
(
configMap
.
containsKey
(
"realm"
))
nvps
.
add
(
new
BasicNameValuePair
(
"realm"
,
configMap
.
get
(
"realm"
)));
httpPost
.
setEntity
(
new
UrlEncodedFormEntity
(
nvps
));
CloseableHttpResponse
response
=
httpClient
.
execute
(
targetHost
,
httpPost
,
context
);
try
{
HttpEntity
entity
=
response
.
getEntity
();
String
responseString
=
EntityUtils
.
toString
(
entity
);
logger
.
trace
(
responseString
);
return
resultParser
.
parseInitAuthenticatorTokenResponse
(
responseString
);
}
finally
{
response
.
close
();
}
}
catch
(
ParseException
|
IOException
e
)
{
throw
new
TwoFaException
(
e
);
}
}
public
LinotpSimpleResponse
disableToken
(
String
serial
)
throws
TwoFaException
{
try
{
HttpPost
httpPost
=
new
HttpPost
(
configMap
.
get
(
"url"
)
+
"/admin/disable"
);
...
...
@@ -215,6 +280,32 @@ public class LinotpConnection {
}
}
public
LinotpSimpleResponse
deleteToken
(
String
serial
)
throws
TwoFaException
{
try
{
HttpPost
httpPost
=
new
HttpPost
(
configMap
.
get
(
"url"
)
+
"/admin/remove"
);
List
<
NameValuePair
>
nvps
=
new
ArrayList
<
NameValuePair
>();
if
(
configMap
.
containsKey
(
"realm"
))
nvps
.
add
(
new
BasicNameValuePair
(
"realm"
,
configMap
.
get
(
"realm"
)));
nvps
.
add
(
new
BasicNameValuePair
(
"session"
,
adminSession
));
nvps
.
add
(
new
BasicNameValuePair
(
"serial"
,
serial
));
httpPost
.
setEntity
(
new
UrlEncodedFormEntity
(
nvps
));
CloseableHttpResponse
response
=
httpClient
.
execute
(
targetHost
,
httpPost
,
context
);
try
{
HttpEntity
entity
=
response
.
getEntity
();
String
responseString
=
EntityUtils
.
toString
(
entity
);
logger
.
trace
(
responseString
);
return
resultParser
.
parseSimpleResponse
(
responseString
);
}
finally
{
response
.
close
();
}
}
catch
(
ParseException
|
IOException
e
)
{
throw
new
TwoFaException
(
e
);
}
}
public
LinotpShowUserResponse
getTokenList
(
UserEntity
user
)
throws
TwoFaException
{
try
{
...
...
bwreg-webapp/src/main/java/edu/kit/scc/webreg/bean/TwoFaUserBean.java
View file @
14e9b179
...
...
@@ -17,6 +17,7 @@ import javax.faces.bean.ViewScoped;
import
javax.faces.event.ComponentSystemEvent
;
import
javax.inject.Inject
;
import
org.primefaces.PrimeFaces
;
import
org.slf4j.Logger
;
import
edu.kit.scc.webreg.entity.UserEntity
;
...
...
@@ -54,8 +55,13 @@ public class TwoFaUserBean implements Serializable {
private
LinotpTokenResultList
tokenList
;
private
LinotpInitAuthenticatorTokenResponse
createTokenResponse
;
private
String
totpCode
,
yubicoCode
;
private
String
defaultButton
;
public
void
preRenderView
(
ComponentSystemEvent
ev
)
{
defaultButton
=
"yubicoStartButton"
;
if
(
user
==
null
)
{
try
{
tokenList
=
twoFaService
.
findByUserId
(
sessionManager
.
getUserId
());
...
...
@@ -76,7 +82,55 @@ public class TwoFaUserBean implements Serializable {
logger
.
warn
(
"TwoFaException"
,
e
);
}
}
public
void
createYubicoToken
()
{
try
{
LinotpInitAuthenticatorTokenResponse
response
=
twoFaService
.
createYubicoToken
(
user
.
getId
(),
yubicoCode
);
if
(
response
.
getResult
().
isStatus
()
&&
response
.
getResult
().
isValue
())
{
tokenList
=
twoFaService
.
findByUserId
(
sessionManager
.
getUserId
());
}
else
{
messageGenerator
.
addResolvedWarningMessage
(
"warn"
,
"twofa_token_failed"
,
true
);
}
PrimeFaces
.
current
().
executeScript
(
"PF('addYubicoDlg').hide();"
);
createTokenResponse
=
null
;
yubicoCode
=
""
;
}
catch
(
TwoFaException
e
)
{
logger
.
warn
(
"TwoFaException"
,
e
);
}
}
public
void
checkAuthenticatorToken
()
{
try
{
if
(
createTokenResponse
!=
null
&&
createTokenResponse
.
getDetail
()
!=
null
)
{
String
serial
=
createTokenResponse
.
getDetail
().
getSerial
();
LinotpSimpleResponse
response
=
twoFaService
.
enableToken
(
user
.
getId
(),
serial
);
if
(
response
.
getResult
()
!=
null
&&
response
.
getResult
().
isStatus
()
&&
response
.
getResult
().
isValue
())
{
response
=
twoFaService
.
checkSpecificToken
(
user
.
getId
(),
serial
,
totpCode
);
if
(
response
.
getResult
()
!=
null
&&
response
.
getResult
().
isStatus
()
&&
response
.
getResult
().
isValue
())
{
// success, Token stays active
tokenList
=
twoFaService
.
findByUserId
(
sessionManager
.
getUserId
());
PrimeFaces
.
current
().
executeScript
(
"PF('addTotpDlg').hide();"
);
createTokenResponse
=
null
;
totpCode
=
""
;
}
else
{
// wrong code, disable token
response
=
twoFaService
.
disableToken
(
user
.
getId
(),
serial
);
totpCode
=
""
;
}
}
}
}
catch
(
TwoFaException
e
)
{
logger
.
warn
(
"TwoFaException"
,
e
);
}
}
public
void
enableToken
(
String
serial
)
{
try
{
LinotpSimpleResponse
response
=
twoFaService
.
enableToken
(
user
.
getId
(),
serial
);
...
...
@@ -111,6 +165,23 @@ public class TwoFaUserBean implements Serializable {
}
}
public
void
deleteToken
(
String
serial
)
{
try
{
LinotpSimpleResponse
response
=
twoFaService
.
deleteToken
(
user
.
getId
(),
serial
);
tokenList
=
twoFaService
.
findByUserId
(
sessionManager
.
getUserId
());
if
((
response
.
getResult
()
!=
null
)
&&
response
.
getResult
().
isStatus
()
&&
response
.
getResult
().
isValue
())
{
messageGenerator
.
addInfoMessage
(
"Info"
,
"Token "
+
serial
+
" deleted"
);
}
else
{
messageGenerator
.
addWarningMessage
(
"Warn"
,
"Token "
+
serial
+
" could not be deleted"
);
}
}
catch
(
TwoFaException
e
)
{
logger
.
warn
(
"TwoFaException"
,
e
);
messageGenerator
.
addErrorMessage
(
"Error"
,
e
.
toString
());
}
}
public
Boolean
getReadOnly
()
{
return
tokenList
.
getReadOnly
();
}
...
...
@@ -131,4 +202,28 @@ public class TwoFaUserBean implements Serializable {
return
createTokenResponse
;
}
public
String
getTotpCode
()
{
return
totpCode
;
}
public
void
setTotpCode
(
String
totpCode
)
{
this
.
totpCode
=
totpCode
;
}
public
String
getDefaultButton
()
{
return
defaultButton
;
}
public
void
setDefaultButton
(
String
defaultButton
)
{
this
.
defaultButton
=
defaultButton
;
}
public
String
getYubicoCode
()
{
return
yubicoCode
;
}
public
void
setYubicoCode
(
String
yubicoCode
)
{
this
.
yubicoCode
=
yubicoCode
;
}
}
bwreg-webapp/src/main/webapp/user/twofa.xhtml
View file @
14e9b179
...
...
@@ -36,7 +36,7 @@
</p:repeat>
</p:panel>
<p:dataGrid
var=
"token"
value=
"#{twoFaUserBean.tokenList}"
columns=
"
1
"
styleClass=
"whitefoot"
<p:dataGrid
var=
"token"
value=
"#{twoFaUserBean.tokenList}"
columns=
"
2
"
styleClass=
"whitefoot"
layout=
"grid"
style=
"margin-bottom: 16px;"
rendered=
"#{! twoFaUserBean.readOnly}"
>
<f:facet
name=
"header"
>
#{messages.twofa_list}
</f:facet>
<p:panel
styleClass=
"grayback"
style=
"margin-bottom: 0px;"
>
...
...
@@ -44,22 +44,100 @@
<i
class=
"fa fa-fw fa-key"
></i>
<b><h:outputText
value=
"#{token.serial}"
/></b>
</f:facet>
<div><h:outputText
value=
"#{token.tokenType}"
/></div>
<div><h:outputText
value=
"#{token.isactive}"
/></div>
<h:panelGrid
columns=
"2"
>
<p:outputLabel
for=
"@next"
value=
"#{messages.twofa_tokentype}:"
/>
<h:panelGroup>
<h:outputText
value=
"#{messages.twofa_tokentype_totp}"
rendered=
"#{token.tokenType == 'TOTP' and token.serial.startsWith('TOTP')}"
/>
<h:outputText
value=
"#{messages.twofa_tokentype_totp_hardware}"
rendered=
"#{token.tokenType == 'TOTP' and not token.serial.startsWith('TOTP')}"
/>
<h:outputText
value=
"#{messages.twofa_tokentype_tanlist}"
rendered=
"#{token.tokenType == 'HOTP'}"
/>
<h:outputText
value=
"#{messages.twofa_tokentype_yubikey}"
rendered=
"#{token.tokenType == 'yubico'}"
/>
</h:panelGroup>
<p:outputLabel
for=
"@next"
value=
"#{messages.twofa_active}:"
/>
<h:outputText
value=
"#{token.isactive ? messages.yes : messages.no}"
/>
</h:panelGrid>
<p:commandButton
action=
"#{twoFaUserBean.disableToken(token.serial)}"
value=
"Disable"
update=
"@form"
rendered=
"#{token.isactive}"
/>
<p:commandButton
action=
"#{twoFaUserBean.enableToken(token.serial)}"
value=
"Enable"
update=
"@form"
rendered=
"#{! token.isactive}"
/>
<p:commandButton
action=
"#{twoFaUserBean.deleteToken(token.serial)}"
value=
"Delete"
update=
"@form"
rendered=
"#{! token.isactive}"
>
<p:confirm
header=
"#{messages.confirm_header}"
message=
"#{messages.confirm}"
/>
</p:commandButton>
</p:panel>
<f:facet
name=
"footer"
>
<p:commandButton
action=
"#{twoFaUserBean.createAuthenticatorToken()}"
value=
"Create"
update=
"@form"
></p:commandButton>
</f:facet>
</p:dataGrid>
<p:panel
rendered=
"#{! twoFaUserBean.readOnly}"
>
<h:outputText
value=
"#{twoFaUserBean.createTokenResponse.detail.googleurl.img}"
escape=
"false"
/>
<h:outputText
value=
"#{twoFaUserBean.createTokenResponse.detail.serial}"
/>
<p:panel>
<div>
<h:outputText
value=
"#{messages.twofa_create_new_token}"
/>
</div>
<p:commandButton
id=
"openAddTotpDialog"
oncomplete=
"PF('addTotpDlg').show();"
value=
"#{messages.twofa_create_new_totp}"
></p:commandButton>
<p:commandButton
id=
"openAddYubicoDialog"
oncomplete=
"PF('addYubicoDlg').show();"
value=
"#{messages.twofa_create_new_yubico}"
></p:commandButton>
</p:panel>
<p:dialog
header=
"#{messages.twofa_create_totp_token}"
widgetVar=
"addTotpDlg"
id=
"addTotpDlgId"
modal=
"true"
closable=
"false"
closeOnEscape=
"true"
showEffect=
"fade"
hideEffect=
"fade"
>
<p:ajax
event=
"close"
update=
"@form"
/>
<div
class=
"panel"
style=
"width:360px;"
>
<h:outputText
value=
"#{messages.twofa_create_totp_token_desc}"
/>
</div>
<p:panel
id=
"totpResponsePanel"
>
<p:commandButton
id=
"totpStartButton"
action=
"#{twoFaUserBean.createAuthenticatorToken()}"
value=
"#{messages.start}"
update=
"totpResponsePanel"
rendered=
"#{empty twoFaUserBean.createTokenResponse}"
/>
<h:panelGroup
rendered=
"#{not empty twoFaUserBean.createTokenResponse}"
>
<div>
<h:outputText
value=
"#{twoFaUserBean.createTokenResponse.detail.googleurl.img}"
escape=
"false"
/>
</div>
<h:panelGrid
columns=
"2"
>
<p:outputLabel
for=
"@next"
value=
"#{messages.twofa_serial}:"
/>
<h:outputText
value=
"#{twoFaUserBean.createTokenResponse.detail.serial}"
/>
<p:outputLabel
for=
"@next"
value=
"#{messages.twofa_code}:"
/>
<p:inputText
id=
"totpText"
value=
"#{twoFaUserBean.totpCode}"
/>
</h:panelGrid>
<p:commandButton
id=
"checkTotpButton"
action=
"#{twoFaUserBean.checkAuthenticatorToken()}"
value=
"#{messages.check}"
update=
"totpResponsePanel"
/>
</h:panelGroup>
</p:panel>
</p:dialog>
<p:dialog
header=
"#{messages.twofa_create_yubico_token}"
widgetVar=
"addYubicoDlg"
id=
"addYubicoDlgId"
modal=
"true"
closable=
"false"
closeOnEscape=
"true"
showEffect=
"fade"
hideEffect=
"fade"
>
<p:ajax
event=
"close"
update=
"@form"
/>
<div
class=
"panel"
style=
"width:360px;"
>
<h:outputText
value=
"#{messages.twofa_create_yubico_token_desc}"
/>
</div>
<p:panel
id=
"yubicoResponsePanel"
>
<h:panelGrid
columns=
"2"
>
<p:outputLabel
for=
"@next"
value=
"#{messages.twofa_code}:"
/>
<p:inputText
id=
"yubicoText"
value=
"#{twoFaUserBean.yubicoCode}"
/>
</h:panelGrid>
<p:commandButton
id=
"yubicoStartButton"
action=
"#{twoFaUserBean.createYubicoToken()}"
value=
"#{messages.start}"
update=
"yubicoResponsePanel"
/>
</p:panel>
</p:dialog>
<p:dialog
header=
"#{messages.twofa_create_backuptan_token}"
widgetVar=
"addBackuptanDlg"
id=
"addBackuptanDlgId"
modal=
"true"
closable=
"false"
closeOnEscape=
"true"
showEffect=
"fade"
hideEffect=
"fade"
>
</p:dialog>
<p:confirmDialog
global=
"true"
showEffect=
"fade"
hideEffect=
"fade"
closable=
"false"
closeOnEscape=
"true"
>
<p:commandButton
value=
"#{messages.yes}"
type=
"button"
styleClass=
"ui-confirmdialog-yes"
/>
<p:commandButton
value=
"#{messages.no}"
type=
"button"
styleClass=
"ui-confirmdialog-no"
/>
</p:confirmDialog>
<p:defaultCommand
target=
"yubicoStartButton"
scope=
"addYubicoDlgId"
/>
<p:defaultCommand
target=
"checkTotpButton"
scope=
"addTotpDlgId"
/>
</h:form>
</ui:define>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment