提交 a526e7a5 编写于 作者: MaxKey单点登录官方's avatar MaxKey单点登录官方

JWT独立子项目

上级 4f349783
......@@ -42,5 +42,7 @@ public final class ConstantsProtocols {
public static final String OPEN_ID_CONNECT = "OpenID_Connect";
public static final String CAS = "CAS";
public static final String JWT = "JWT";
}
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
*/
package org.maxkey.domain.apps;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author Crystal.Sea
*
*/
@Table(name = "MXK_APPS_JWT_DETAILS")
public class AppsJwtDetails extends Apps {
/**
*
*/
private static final long serialVersionUID = -1717427271305620545L;
@Id
@Column
@GeneratedValue(strategy=GenerationType.AUTO,generator="uuid")
protected String id;
/**
*
*/
@Column
private String redirectUri;
//
@Column
private String tokenType;
@Column
private String cookieName;
@Column
private String algorithm;
@Column
private String algorithmKey;
@Column
private String expires;
public AppsJwtDetails() {
super();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getRedirectUri() {
return redirectUri;
}
public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
}
public String getTokenType() {
return tokenType;
}
public void setTokenType(String tokenType) {
this.tokenType = tokenType;
}
public String getCookieName() {
return cookieName;
}
public void setCookieName(String cookieName) {
this.cookieName = cookieName;
}
public String getAlgorithm() {
return algorithm;
}
public void setAlgorithm(String algorithm) {
this.algorithm = algorithm;
}
public String getAlgorithmKey() {
return algorithmKey;
}
public void setAlgorithmKey(String algorithmKey) {
this.algorithmKey = algorithmKey;
}
public String getExpires() {
return expires;
}
public void setExpires(String expires) {
this.expires = expires;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("AppsTokenBasedDetails [id=");
builder.append(id);
builder.append(", redirectUri=");
builder.append(redirectUri);
builder.append(", tokenType=");
builder.append(tokenType);
builder.append(", cookieName=");
builder.append(cookieName);
builder.append(", algorithm=");
builder.append(algorithm);
builder.append(", algorithmKey=");
builder.append(algorithmKey);
builder.append(", expires=");
builder.append(expires);
builder.append("]");
return builder.toString();
}
}
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
*/
package org.maxkey.persistence.mapper;
import org.apache.mybatis.jpa.persistence.IJpaBaseMapper;
import org.maxkey.domain.apps.AppsJwtDetails;
/**
* @author Crystal.sea
*
*/
public interface AppsJwtDetailsMapper extends IJpaBaseMapper<AppsJwtDetails> {
public AppsJwtDetails getAppDetails(String id);
}
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.persistence.service;
import org.apache.mybatis.jpa.persistence.JpaBaseService;
import org.maxkey.domain.apps.AppsJwtDetails;
import org.maxkey.persistence.mapper.AppsJwtDetailsMapper;
import org.springframework.stereotype.Service;
@Service
public class AppsJwtDetailsService extends JpaBaseService<AppsJwtDetails>{
public AppsJwtDetailsService() {
super(AppsJwtDetailsMapper.class);
}
/* (non-Javadoc)
* @see com.connsec.db.service.BaseService#getMapper()
*/
@Override
public AppsJwtDetailsMapper getMapper() {
// TODO Auto-generated method stub
return (AppsJwtDetailsMapper)super.getMapper();
}
public AppsJwtDetails getAppDetails(String id) {
return getMapper().getAppDetails(id);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.maxkey.persistence.mapper.AppsJwtDetailsMapper">
<select id="getAppDetails" parameterType="string" resultType="AppsJwtDetails">
SELECT
*
FROM
MXK_APPS_JWT_DETAILS JD,
MXK_APPS APP
WHERE
APP.ID = #{value}
AND JD.ID = #{value}
AND JD.ID = APP.ID
AND STATUS = 1
</select>
</mapper>
\ No newline at end of file
......@@ -68,7 +68,9 @@ public class AuthorizeEndpoint extends AuthorizeBaseEndpoint{
modelAndView=WebContext.forward("/authz/tokenbased/"+id);
}else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.CAS)){
modelAndView=WebContext.forward("/authz/cas/"+id);
}else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.DESKTOP)){
}else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.JWT)){
modelAndView=WebContext.forward("/authz/jwt/"+id);
}else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.DESKTOP)){
modelAndView=WebContext.forward("/authz/desktop/"+id);
}else if (application.getProtocol().equalsIgnoreCase(ConstantsProtocols.BASIC)){
modelAndView=WebContext.redirect(application.getLoginUrl());
......@@ -78,14 +80,5 @@ public class AuthorizeEndpoint extends AuthorizeBaseEndpoint{
return modelAndView;
}
@RequestMapping("/authz/oauth10a/{id}")
public ModelAndView authorizeOAuth10a(
@PathVariable("id") String id){
String redirec_uri=getApp(id).getLoginUrl();
return WebContext.redirect(redirec_uri);
}
}
description = "maxkey-protocol-jwt"
dependencies {
//local jars
compile fileTree(dir: '../maxkey-lib/*/', include: '*.jar')
compile project(":maxkey-core")
compile project(":maxkey-persistence")
compile project(":maxkey-protocols:maxkey-protocol-authorize")
}
\ No newline at end of file
......@@ -15,7 +15,7 @@
*/
package org.maxkey.authz.token.endpoint.adapter;
package org.maxkey.authz.jwt.endpoint.adapter;
import java.util.Arrays;
import java.util.Date;
......@@ -28,7 +28,7 @@ import org.maxkey.configuration.oidc.OIDCProviderMetadata;
import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService;
import org.maxkey.domain.UserInfo;
import org.maxkey.domain.apps.Apps;
import org.maxkey.domain.apps.AppsTokenBasedDetails;
import org.maxkey.domain.apps.AppsJwtDetails;
import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
......@@ -42,11 +42,11 @@ import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.SignedJWT;
public class TokenBasedJWTAdapter extends AbstractAuthorizeAdapter {
final static Logger _logger = LoggerFactory.getLogger(TokenBasedJWTAdapter.class);
public class JwtAdapter extends AbstractAuthorizeAdapter {
final static Logger _logger = LoggerFactory.getLogger(JwtAdapter.class);
@Override
public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) {
AppsTokenBasedDetails details=(AppsTokenBasedDetails)app;
AppsJwtDetails details=(AppsJwtDetails)app;
JwtSigningAndValidationService jwtSignerService= (JwtSigningAndValidationService)WebContext.getBean("jwtSignerValidationService");
......@@ -111,8 +111,8 @@ public class TokenBasedJWTAdapter extends AbstractAuthorizeAdapter {
@Override
public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) {
modelAndView.setViewName("authorize/tokenbased_jwt_sso_submint");
AppsTokenBasedDetails details=(AppsTokenBasedDetails)app;
modelAndView.setViewName("authorize/jwt_sso_submint");
AppsJwtDetails details=(AppsJwtDetails)app;
modelAndView.addObject("action", details.getRedirectUri());
_logger.debug("jwt Token data : "+data);
......
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.authz.jwt.endpoint.adapter;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;
import org.joda.time.DateTime;
import org.maxkey.authn.SigninPrincipal;
import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter;
import org.maxkey.configuration.oidc.OIDCProviderMetadata;
import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService;
import org.maxkey.domain.UserInfo;
import org.maxkey.domain.apps.AppsJwtDetails;
import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.SignedJWT;
public class JwtDefaultAdapter extends AbstractAuthorizeAdapter {
final static Logger _logger = LoggerFactory.getLogger(JwtDefaultAdapter.class);
@Override
public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) {
AppsJwtDetails details=(AppsJwtDetails)app;
JwtSigningAndValidationService jwtSignerService= (JwtSigningAndValidationService)WebContext.getBean("jwtSignerValidationService");
OIDCProviderMetadata providerMetadata= (OIDCProviderMetadata)WebContext.getBean("oidcProviderMetadata");
DateTime currentDateTime=DateTime.now();
Date expirationTime=currentDateTime.plusMinutes(Integer.parseInt(details.getExpires())).toDate();
_logger.debug("expiration Time : "+expirationTime);
JWTClaimsSet jwtClaims =new JWTClaimsSet.Builder()
.issuer(providerMetadata.getIssuer())
.subject(userInfo.getUsername())
.audience(Arrays.asList(details.getId()))
.jwtID(UUID.randomUUID().toString())
.issueTime(currentDateTime.toDate())
.expirationTime(expirationTime)
.claim("email", userInfo.getWorkEmail())
.claim("name", userInfo.getUsername())
.claim("user_id", userInfo.getId())
.claim("external_id", userInfo.getId())
.claim("locale", userInfo.getLocale())
.claim(WebConstants.ONLINE_TICKET_NAME, authentication.getOnlineTicket().getTicketId())
.claim("kid", jwtSignerService.getDefaultSignerKeyId())
.build();
_logger.debug("jwt Claims : "+jwtClaims);
JWT jwtToken = new PlainJWT(jwtClaims);
JWSAlgorithm signingAlg = jwtSignerService.getDefaultSigningAlgorithm();
//get PublicKey
/*Map<String, JWK> jwkMap=jwtSignerService.getAllPublicKeys();
JWK jwk=jwkMap.get("connsec_rsa1");
_logger.debug("isPrivate "+jwk.isPrivate());*/
_logger.debug(" signingAlg "+signingAlg);
jwtToken = new SignedJWT(new JWSHeader(signingAlg), jwtClaims);
// sign it with the server's key
jwtSignerService.signJwt((SignedJWT) jwtToken);
String tokenString=jwtToken.serialize();
_logger.debug("jwt Token : "+tokenString);
return tokenString;
}
@Override
public String encrypt(String data, String algorithmKey, String algorithm) {
return super.encrypt(data, algorithmKey, algorithm);
}
@Override
public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) {
modelAndView.setViewName("authorize/jwt_sso_submint");
AppsJwtDetails details=(AppsJwtDetails)app;
modelAndView.addObject("action", details.getRedirectUri());
modelAndView.addObject("token",data );
return modelAndView;
}
}
......@@ -15,7 +15,7 @@
*/
package org.maxkey.authz.token.endpoint.adapter;
package org.maxkey.authz.jwt.endpoint.adapter;
import java.util.Arrays;
import java.util.Date;
......@@ -30,7 +30,7 @@ import org.maxkey.crypto.jwt.signer.service.JwtSigningAndValidationService;
import org.maxkey.crypto.jwt.signer.service.impl.SymmetricSigningAndValidationServiceBuilder;
import org.maxkey.domain.UserInfo;
import org.maxkey.domain.apps.Apps;
import org.maxkey.domain.apps.AppsTokenBasedDetails;
import org.maxkey.domain.apps.AppsJwtDetails;
import org.maxkey.web.WebConstants;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
......@@ -44,13 +44,13 @@ import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.SignedJWT;
public class TokenBasedJWTHS256Adapter extends AbstractAuthorizeAdapter {
final static Logger _logger = LoggerFactory.getLogger(TokenBasedJWTHS256Adapter.class);
public class JwtHS256Adapter extends AbstractAuthorizeAdapter {
final static Logger _logger = LoggerFactory.getLogger(JwtHS256Adapter.class);
private SymmetricSigningAndValidationServiceBuilder symmetricJwtSignerServiceBuilder=new SymmetricSigningAndValidationServiceBuilder();
@Override
public String generateInfo(SigninPrincipal authentication,UserInfo userInfo,Object app) {
AppsTokenBasedDetails details=(AppsTokenBasedDetails)app;
AppsJwtDetails details=(AppsJwtDetails)app;
OIDCProviderMetadata providerMetadata= (OIDCProviderMetadata)WebContext.getBean("oidcProviderMetadata");
......@@ -108,8 +108,8 @@ public class TokenBasedJWTHS256Adapter extends AbstractAuthorizeAdapter {
@Override
public ModelAndView authorize(UserInfo userInfo, Object app, String data,ModelAndView modelAndView) {
modelAndView.setViewName("authorize/tokenbased_jwt_sso_submint");
AppsTokenBasedDetails details=(AppsTokenBasedDetails)app;
modelAndView.setViewName("authorize/jwt_sso_submint");
AppsJwtDetails details=(AppsJwtDetails)app;
modelAndView.addObject("action", details.getRedirectUri());
_logger.debug("jwt Token data : "+data);
......
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
*/
package org.maxkey.authz.token.endpoint;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.maxkey.authn.SigninPrincipal;
import org.maxkey.authz.endpoint.AuthorizeBaseEndpoint;
import org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter;
import org.maxkey.authz.jwt.endpoint.adapter.JwtDefaultAdapter;
import org.maxkey.configuration.ApplicationConfig;
import org.maxkey.constants.Boolean;
import org.maxkey.domain.apps.Apps;
import org.maxkey.domain.apps.AppsJwtDetails;
import org.maxkey.persistence.service.AppsJwtDetailsService;
import org.maxkey.util.Instance;
import org.maxkey.web.WebContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* @author Crystal.Sea
*
*/
@Controller
public class JwtAuthorizeEndpoint extends AuthorizeBaseEndpoint{
final static Logger _logger = LoggerFactory.getLogger(JwtAuthorizeEndpoint.class);
@Autowired
AppsJwtDetailsService jwtDetailsService;
JwtDefaultAdapter jwtDefaultAdapter=new JwtDefaultAdapter();
@Autowired
ApplicationConfig applicationConfig;
@RequestMapping("/authz/jwt/{id}")
public ModelAndView authorize(
HttpServletRequest request,
HttpServletResponse response,
@PathVariable("id") String id){
ModelAndView modelAndView=new ModelAndView();
AppsJwtDetails jwtDetails=null;
jwtDetails=jwtDetailsService.getAppDetails(id);
_logger.debug(""+jwtDetails);
Apps application= getApp(id);
jwtDetails.setAdapter(application.getAdapter());
jwtDetails.setIsAdapter(application.getIsAdapter());
AbstractAuthorizeAdapter adapter;
if(Boolean.isTrue(jwtDetails.getIsAdapter())){
adapter =(AbstractAuthorizeAdapter)Instance.newInstance(jwtDetails.getAdapter());
}else{
adapter =(AbstractAuthorizeAdapter)jwtDefaultAdapter;
}
String tokenData=adapter.generateInfo(
(SigninPrincipal)WebContext.getAuthentication().getPrincipal(),
WebContext.getUserInfo(),
jwtDetails);
String encryptTokenData=adapter.encrypt(
tokenData,
jwtDetails.getAlgorithmKey(),
jwtDetails.getAlgorithm());
String signTokenData=adapter.sign(
encryptTokenData,
jwtDetails);
if(jwtDetails.getTokenType().equalsIgnoreCase("POST")) {
modelAndView=adapter.authorize(
WebContext.getUserInfo(),
jwtDetails,
signTokenData,
modelAndView);
return modelAndView;
}else {
String cookieValue="";
cookieValue=signTokenData;
_logger.debug("Cookie Name : "+jwtDetails.getCookieName());
Cookie cookie= new Cookie(jwtDetails.getCookieName(),cookieValue);
Integer maxAge=Integer.parseInt(jwtDetails.getExpires())*60;
_logger.debug("Cookie Max Age :"+maxAge+" seconds.");
cookie.setMaxAge(maxAge);
cookie.setPath("/");
//
//cookie.setDomain("."+applicationConfig.getBaseDomainName());
//tomcat 8.5
cookie.setDomain(applicationConfig.getBaseDomainName());
_logger.debug("Sub Domain Name : "+"."+applicationConfig.getBaseDomainName());
response.addCookie(cookie);
if(jwtDetails.getRedirectUri().indexOf(applicationConfig.getBaseDomainName())>-1){
return WebContext.redirect(jwtDetails.getRedirectUri());
}else{
_logger.error(jwtDetails.getRedirectUri()+" not in domain "+applicationConfig.getBaseDomainName());
return null;
}
}
}
}
/*
* Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.maxkey.web.apps.contorller;
import org.maxkey.constants.ConstantsOperateMessage;
import org.maxkey.constants.ConstantsProtocols;
import org.maxkey.crypto.ReciprocalUtils;
import org.maxkey.domain.apps.AppsJwtDetails;
import org.maxkey.persistence.service.AppsJwtDetailsService;
import org.maxkey.web.WebContext;
import org.maxkey.web.message.Message;
import org.maxkey.web.message.MessageType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping(value={"/apps/jwt"})
public class JwtDetailsController extends BaseAppContorller {
final static Logger _logger = LoggerFactory.getLogger(JwtDetailsController.class);
@Autowired
AppsJwtDetailsService jwtDetailsService;
@RequestMapping(value = { "/forwardAdd" })
public ModelAndView forwardAdd() {
ModelAndView modelAndView=new ModelAndView("apps/jwt/appAdd");
AppsJwtDetails jwtDetails =new AppsJwtDetails();
jwtDetails.setId(jwtDetails.generateId());
jwtDetails.setProtocol(ConstantsProtocols.JWT);
jwtDetails.setSecret(ReciprocalUtils.generateKey(ReciprocalUtils.Algorithm.AES));
jwtDetails.setAlgorithmKey(jwtDetails.getSecret());
jwtDetails.setUserPropertys("userPropertys");
modelAndView.addObject("model",jwtDetails);
return modelAndView;
}
@RequestMapping(value={"/add"})
public ModelAndView insert(@ModelAttribute("jwtDetails") AppsJwtDetails jwtDetails) {
_logger.debug("-Add :" + jwtDetails);
transform(jwtDetails);
jwtDetails.setAlgorithmKey(jwtDetails.getSecret());
if (jwtDetailsService.insert(jwtDetails)&&appsService.insertApp(jwtDetails)) {
new Message(WebContext.getI18nValue(ConstantsOperateMessage.INSERT_SUCCESS),MessageType.success);
} else {
new Message(WebContext.getI18nValue(ConstantsOperateMessage.INSERT_SUCCESS),MessageType.error);
}
return WebContext.forward("forwardUpdate/"+jwtDetails.getId());
}
@RequestMapping(value = { "/forwardUpdate/{id}" })
public ModelAndView forwardUpdate(@PathVariable("id") String id) {
ModelAndView modelAndView=new ModelAndView("apps/jwt/appUpdate");
AppsJwtDetails jwtDetails=jwtDetailsService.getAppDetails(id);
decoderSecret(jwtDetails);
String algorithmKey=passwordReciprocal.decoder(jwtDetails.getAlgorithmKey());
jwtDetails.setAlgorithmKey(algorithmKey);
WebContext.setAttribute(jwtDetails.getId(), jwtDetails.getIcon());
modelAndView.addObject("model",jwtDetails);
return modelAndView;
}
/**
* modify
* @param application
* @return
*/
@RequestMapping(value={"/update"})
public ModelAndView update(@ModelAttribute("jwtDetails") AppsJwtDetails jwtDetails) {
//
_logger.debug("-update application :" + jwtDetails);
transform(jwtDetails);
jwtDetails.setAlgorithmKey(jwtDetails.getSecret());
if (jwtDetailsService.update(jwtDetails)&&appsService.updateApp(jwtDetails)) {
new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_SUCCESS),MessageType.success);
} else {
new Message(WebContext.getI18nValue(ConstantsOperateMessage.UPDATE_ERROR),MessageType.error);
}
return WebContext.forward("forwardUpdate/"+jwtDetails.getId());
}
@ResponseBody
@RequestMapping(value={"/delete/{id}"})
public Message delete(@PathVariable("id") String id) {
_logger.debug("-delete application :" + id);
if (jwtDetailsService.remove(id)&&appsService.remove(id)) {
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.DELETE_SUCCESS),MessageType.success);
} else {
return new Message(WebContext.getI18nValue(ConstantsOperateMessage.DELETE_SUCCESS),MessageType.error);
}
}
}
......@@ -2,7 +2,7 @@
#application
application.title=MaxKey
application.name=MaxKey-Mgt
application.formatted-version=v2.3.0 GA
application.formatted-version=v2.4.0 GA
#server config
#server port
server.port=9521
......
......@@ -269,6 +269,7 @@ apps.protocol.oauth2.0=OAuth2.0
apps.protocol.saml2.0=SAML2.0
apps.protocol.ltpa=\u8f7b\u91cf\u7ea7\u8ba4\u8bc1(LTPA)
apps.protocol.cas=CAS\u8ba4\u8bc1
apps.protocol.jwt=JWT\u4ee4\u724c
apps.protocol.extendapi=API\u6269\u5c55\u8ba4\u8bc1
apps.protocol.basic=\u57fa\u672c\u767b\u5f55
apps.vendor=\u4f9b\u5e94\u5546
......@@ -339,6 +340,15 @@ apps.tokenbased.algorithm=\u52a0\u5bc6\u7b97\u6cd5
apps.tokenbased.algorithmKey=\u79d8\u94a5
apps.tokenbased.token.content=\u4ee4\u724c\u5185\u5bb9
apps.tokenbased.expires=\u8fc7\u671f\u65f6\u95f4
#JWT
apps.jwt.info=JWT\u8ba4\u8bc1
apps.jwt.redirectUri=\u8ba4\u8bc1\u5730\u5740
apps.jwt.tokenType=\u4ee4\u724c\u7c7b\u578b
apps.jwt.cookieName=Cookie\u540d\u79f0
apps.jwt.algorithm=\u52a0\u5bc6\u7b97\u6cd5
apps.jwt.algorithmKey=\u79d8\u94a5
apps.jwt.content=\u4ee4\u724c\u5185\u5bb9
apps.jwt.expires=\u8fc7\u671f\u65f6\u95f4
#SAML
apps.saml.metadata.company=\u516c\u53f8
apps.saml.spAcsUrl=SP ACS Url
......
......@@ -269,6 +269,7 @@ apps.protocol.oauth2.0=OAuth2.0
apps.protocol.saml2.0=SAML2.0
apps.protocol.ltpa=Lightweight Third-Party(LTPA)
apps.protocol.cas=CAS
apps.protocol.jwt=JwtToken
apps.protocol.extendapi=API Extend
apps.protocol.basic=Basic
apps.vendor=vendor
......@@ -338,6 +339,15 @@ apps.tokenbased.algorithm=algorithm
apps.tokenbased.algorithmKey=algorithmKey
apps.tokenbased.token.content=content
apps.tokenbased.expires=expires
#jwt
apps.jwt.info=JWT Info
apps.jwt.redirectUri=redirectUri
apps.jwt.tokenType=tokenType
apps.jwt.cookieName=Cookie Name
apps.jwt.algorithm=algorithm
apps.jwt.algorithmKey=algorithmKey
apps.jwt.content=content
apps.jwt.expires=expires
#SAML
apps.saml.metadata.company=company
apps.saml.spAcsUrl=SP ACS Url
......
......@@ -269,6 +269,7 @@ apps.protocol.oauth2.0=OAuth2.0
apps.protocol.saml2.0=SAML2.0
apps.protocol.ltpa=\u8f7b\u91cf\u7ea7\u8ba4\u8bc1(LTPA)
apps.protocol.cas=CAS\u8ba4\u8bc1
apps.protocol.jwt=JWT\u4ee4\u724c
apps.protocol.extendapi=API\u6269\u5c55\u8ba4\u8bc1
apps.protocol.basic=\u57fa\u672c\u767b\u5f55
apps.vendor=\u4f9b\u5e94\u5546
......@@ -339,6 +340,16 @@ apps.tokenbased.algorithm=\u52a0\u5bc6\u7b97\u6cd5
apps.tokenbased.algorithmKey=\u79d8\u94a5
apps.tokenbased.token.content=\u4ee4\u724c\u5185\u5bb9
apps.tokenbased.expires=\u8fc7\u671f\u65f6\u95f4
#JWT
#tokenbased
apps.jwt.info=JWT\u8ba4\u8bc1
apps.jwt.redirectUri=\u8ba4\u8bc1\u5730\u5740
apps.jwt.tokenType=\u4ee4\u724c\u7c7b\u578b
apps.jwt.cookieName=Cookie\u540d\u79f0
apps.jwt.algorithm=\u52a0\u5bc6\u7b97\u6cd5
apps.jwt.algorithmKey=\u79d8\u94a5
apps.jwt.content=\u4ee4\u724c\u5185\u5bb9
apps.jwt.expires=\u8fc7\u671f\u65f6\u95f4
#SAML
apps.saml.metadata.company=\u516c\u53f8
apps.saml.spAcsUrl=SP ACS Url
......
......@@ -24,6 +24,7 @@
protocolArray["CAS"]="cas";
protocolArray["Basic"]="basic";
protocolArray["Desktop"]="desktop";
protocolArray["JWT"]="jwt";
$(function () {
$("#modifyApps").on("click",function(){
......@@ -131,13 +132,14 @@
<@locale code="button.text.add"/>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" target="_blank" href="<@base/>/apps/formbased/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.formbased" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/desktop/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.desktop" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/tokenbased/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.tokenbased" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/oauth20/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.oauth2.0" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/oauth20/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.oauth2.0" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/saml20/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.saml2.0" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/cas/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.cas" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/formbased/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.formbased" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/jwt/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.jwt" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/tokenbased/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.tokenbased" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/extendapi/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.extendapi" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/desktop/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.desktop" /></a>
<a class="dropdown-item" target="_blank" href="<@base/>/apps/basic/forwardAdd">&nbsp;&nbsp;<@locale code="apps.protocol.basic" /></a>
</div>
</div>
......
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<#include "../../layout/header.ftl"/>
<#include "../../layout/common.cssjs.ftl"/>
<#include "../appCommonHead.ftl"/>
</head>
<body>
<form id="actionForm_app" method="post" type="label" autoclose="true" closeWindow="true"
action="<@base/>/apps/jwt/add"
forward="<@base/>/apps/list"
enctype="multipart/form-data"
class="needs-validation" novalidate>
<!-- content -->
<!--table-->
<table width="960" class="table table-bordered" >
<tbody>
<tr>
<td ><#include "../appAddCommon.ftl"/></td>
</tr>
<tr>
<td>
<table width="960" class="table table-bordered" >
<tbody>
<tr>
<td colspan=4><@locale code="apps.jwt.info" /></td>
</tr>
<tr>
<th style="width:15%;"><@locale code="apps.jwt.redirectUri" /></th>
<td style="width:35%;" colspan=3>
<input type="text" class="form-control" id="redirectUri" name="redirectUri" title="" value="" required="" />
</td>
</tr>
<tr>
<th ><@locale code="apps.jwt.tokenType" /></th>
<td >
<select id="tokenType" name="tokenType" class="form-control">
<option value="POST">安全令牌(TOKEN POST)</option>
<option value="LTPA">轻量级认证(LTPA COOKIE)</option>
</select>
</td>
<th ><@locale code="apps.jwt.cookieName" /></th>
<td >
<input type="text" class="form-control" id="cookieName" name="cookieName" title="" value=""/>
</td>
</tr>
<tr>
<th style="width:15%;"><@locale code="apps.jwt.algorithm" /></th>
<td style="width:35%;">
<select id="algorithm" name="algorithm" class="form-control">
<option value="DES">DES</option>
<option value="DESede">DESede</option>
<option value="Blowfish">Blowfish</option>
<option value="AES" selected>AES</option>
<option value="HS256" >HMAC SHA-256</option>
<option value="RS256" >RSA SHA-256</option>
</select>
<b class="orange">*</b><label for="algorithm"></label>
</td>
<th width="140px"><@locale code="apps.jwt.algorithmKey" /></th>
<td width="340px">
<span id="algorithmKey_text">${model.algorithmKey!}</span>
<input type="hidden" class="form-control" id="algorithmKey" name="algorithmKey" title="" value="${model.algorithmKey!}"/>
</td>
</tr>
<tr>
<th><@locale code="apps.jwt.content" /></th>
<td>
<#include "../userPropertys.ftl"/>
</td>
<th><@locale code="apps.jwt.expires" /></th>
<td>
<input type="text" class="form-control" id="expires" name="expires" title="" value="1" required="" />
</td>
</tr>
<tr>
<td colspan =4>
<input class="button" id="status" type="hidden" name="status" value="1"/>
<input class="button btn btn-primary mr-3" id="submitBtn" type="submit" value="<@locale code="button.text.save" />"/>
<input class="button btn btn-secondary mr-3" id="backBtn" type="button" value="<@locale code="button.text.cancel" />"/>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
\ No newline at end of file
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<#include "../../layout/header.ftl"/>
<#include "../../layout/common.cssjs.ftl"/>
<#include "../appCommonHead.ftl"/>
<#setting number_format="#">
</head>
<body>
<form id="actionForm_app" method="post" type="label" autoclose="true" closeWindow="true"
action="<@base/>/apps/jwt/update"
forward="<@base/>/apps/list"
enctype="multipart/form-data"
class="needs-validation" novalidate>
<!-- content -->
<!--table-->
<table width="960" class="table table-bordered" >
<tbody>
<tr>
<td ><#include "../appUpdateCommon.ftl"/></td>
</tr>
<tr>
<td>
<table width="960" class="table table-bordered" >
<tbody>
<tr>
<td colspan=4><@locale code="apps.jwt.info" /></td>
</tr>
<tr>
<th style="width:15%;"><@locale code="apps.jwt.redirectUri" /></th>
<td colspan=3>
<input type="text" id="redirectUri" class="form-control" name="redirectUri" title="" value="${model.redirectUri}" required="" />
</td>
</tr>
<tr>
<th ><@locale code="apps.jwt.tokenType" /></th>
<td >
<select id="tokenType" name="tokenType" class="form-control">
<option value="POST" <#if 'POST'==model.tokenType>selected</#if> >安全令牌(TOKEN POST)</option>
<option value="LTPA" <#if 'LTPA'==model.tokenType>selected</#if> >轻量级认证(LTPA COOKIE)</option>
</select>
</td>
<th ><@locale code="apps.jwt.cookieName" /></th>
<td >
<input type="text" class="form-control" id="cookieName" name="cookieName" title="" value="${model.cookieName!}"/>
</td>
</tr>
<tr>
<th style="width:15%;"><@locale code="apps.jwt.algorithm" /></th>
<td style="width:35%;">
<select id="algorithm" name="algorithm" class="form-control" >
<option value="DES" <#if 'DES'==model.algorithm>selected</#if> >DES</option>
<option value="DESede" <#if 'DESede'==model.algorithm>selected</#if>>DESede</option>
<option value="Blowfish" <#if 'Blowfish'==model.algorithm>selected</#if>>Blowfish</option>
<option value="AES" <#if 'AES'==model.algorithm>selected</#if>>AES</option>
<option value="HS256" <#if 'HS256'==model.algorithm>selected</#if>>HMAC SHA-256</option>
<option value="RS256" <#if 'RS256'==model.algorithm>selected</#if>>RSA SHA-256</option>
</select>
</td>
<th style="width:15%;"><@locale code="apps.jwt.algorithmKey" /></th>
<td style="width:35%;">
<span id="algorithmKey_text">${model.algorithmKey}</span>
<input type="hidden" id="algorithmKey" name="algorithmKey" title="" value="${model.algorithmKey}"/>
</td>
</tr>
<tr>
<th><@locale code="apps.jwt.content" /></th>
<td >
<#include "../userPropertys.ftl"/>
</td>
<th><@locale code="apps.jwt.expires" /></th>
<td>
<input type="text" class="form-control" id="expires" name="expires" title="" value="${model.expires}" required="" />
</td>
</tr>
<tr>
<td colspan =4>
<input class="button btn btn-primary mr-3" id="submitBtn" type="submit" value="<@locale code="button.text.save" />"/>
<input class="button btn btn-secondary mr-3" id="backBtn" type="button" value="<@locale code="button.text.cancel" />"/>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
\ No newline at end of file
......@@ -52,7 +52,7 @@ dependencies {
compile project(":maxkey-protocols:maxkey-protocol-tokenbased")
compile project(":maxkey-protocols:maxkey-protocol-oauth-2.0")
compile project(":maxkey-protocols:maxkey-protocol-saml-2.0")
compile project(":maxkey-protocols:maxkey-protocol-jwt")
compile project(":maxkey-identitys:maxkey-identity-kafka")
}
......
......@@ -2,7 +2,7 @@
#application
application.title=MaxKey
application.name=MaxKey
application.formatted-version=v2.3.0 GA
application.formatted-version=v2.4.0 GA
#server port
#server.port=80
......
......@@ -15,14 +15,15 @@ include 'maxkey-identitys:maxkey-identity-rest'
//Protocol
//include 'maxkey-protocols'
include 'maxkey-protocols:maxkey-protocol-authorize'
include 'maxkey-protocols:maxkey-protocol-oauth-2.0'
include 'maxkey-protocols:maxkey-protocol-saml-2.0'
include 'maxkey-protocols:maxkey-protocol-authorize'
include 'maxkey-protocols:maxkey-protocol-desktop'
include 'maxkey-protocols:maxkey-protocol-extendapi'
include 'maxkey-protocols:maxkey-protocol-cas'
include 'maxkey-protocols:maxkey-protocol-jwt'
include 'maxkey-protocols:maxkey-protocol-formbased'
include 'maxkey-protocols:maxkey-protocol-tokenbased'
include 'maxkey-protocols:maxkey-protocol-cas'
include 'maxkey-protocols:maxkey-protocol-extendapi'
include 'maxkey-protocols:maxkey-protocol-desktop'
//include 'maxkey-webs'
//maxkey
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册