Search in sources :

Example 1 with SigninPrincipal

use of org.maxkey.authn.SigninPrincipal in project MaxKey by dromara.

the class OAuth20AccessConfirmationEndpoint method getAccessConfirmation.

/**
 * getAccessConfirmation.
 * @param model  Map
 * @return
 * throws Exception
 */
@RequestMapping(OAuth2Constants.ENDPOINT.ENDPOINT_APPROVAL_CONFIRM)
public ModelAndView getAccessConfirmation(@RequestParam Map<String, Object> model) {
    try {
        model.remove("authorizationRequest");
        // Map<String, Object> model
        AuthorizationRequest clientAuth = (AuthorizationRequest) WebContext.getAttribute("authorizationRequest");
        ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId(), true);
        Apps app = (Apps) WebContext.getAttribute(WebConstants.AUTHORIZE_SIGN_ON_APP);
        WebContext.setAttribute(app.getId(), app.getIcon());
        model.put("auth_request", clientAuth);
        model.put("client", client);
        model.put("app", app);
        model.put("oauth_version", "oauth 2.0");
        Map<String, String> scopes = new LinkedHashMap<String, String>();
        for (String scope : clientAuth.getScope()) {
            scopes.put(OAuth2Constants.PARAMETER.SCOPE_PREFIX + scope, "false");
        }
        String principal = ((SigninPrincipal) WebContext.getAuthentication().getPrincipal()).getUsername();
        for (Approval approval : approvalStore.getApprovals(principal, client.getClientId())) {
            if (clientAuth.getScope().contains(approval.getScope())) {
                scopes.put(OAuth2Constants.PARAMETER.SCOPE_PREFIX + approval.getScope(), approval.getStatus() == ApprovalStatus.APPROVED ? "true" : "false");
            }
        }
        model.put("scopes", scopes);
        if (!model.containsKey(OAuth2Constants.PARAMETER.APPROVAL_PROMPT)) {
            model.put(OAuth2Constants.PARAMETER.APPROVAL_PROMPT, client.getApprovalPrompt());
        }
    } catch (Exception e) {
        _logger.debug("OAuth Access Confirmation process error.", e);
    }
    ModelAndView modelAndView = new ModelAndView("authorize/oauth_access_confirmation");
    _logger.trace("Confirmation details ");
    for (Object key : model.keySet()) {
        _logger.trace("key " + key + "=" + model.get(key));
    }
    modelAndView.addObject("model", model);
    return modelAndView;
}
Also used : AuthorizationRequest(org.maxkey.authz.oauth2.provider.AuthorizationRequest) ClientDetails(org.maxkey.entity.apps.oauth2.provider.ClientDetails) SigninPrincipal(org.maxkey.authn.SigninPrincipal) ModelAndView(org.springframework.web.servlet.ModelAndView) Approval(org.maxkey.authz.oauth2.provider.approval.Approval) Apps(org.maxkey.entity.apps.Apps) LinkedHashMap(java.util.LinkedHashMap) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 2 with SigninPrincipal

use of org.maxkey.authn.SigninPrincipal in project MaxKey by dromara.

the class OAuth2UserDetailsService method loadUserByUsername.

public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    UserInfo userInfo;
    try {
        userInfo = loginRepository.find(username, "");
    } catch (NoSuchClientException e) {
        throw new UsernameNotFoundException(e.getMessage(), e);
    }
    String onlineTickitId = WebConstants.ONLINE_TICKET_PREFIX + "-" + java.util.UUID.randomUUID().toString().toLowerCase();
    SigninPrincipal signinPrincipal = new SigninPrincipal(userInfo);
    OnlineTicket onlineTicket = new OnlineTicket(onlineTickitId);
    // set OnlineTicket
    signinPrincipal.setOnlineTicket(onlineTicket);
    ArrayList<GrantedAuthority> grantedAuthoritys = loginRepository.grantAuthority(userInfo);
    signinPrincipal.setAuthenticated(true);
    for (GrantedAuthority administratorsAuthority : AbstractAuthenticationProvider.grantedAdministratorsAuthoritys) {
        if (grantedAuthoritys.contains(administratorsAuthority)) {
            signinPrincipal.setRoleAdministrators(true);
            _logger.trace("ROLE ADMINISTRATORS Authentication .");
        }
    }
    _logger.debug("Granted Authority " + grantedAuthoritys);
    signinPrincipal.setGrantedAuthorityApps(grantedAuthoritys);
    return signinPrincipal;
}
Also used : UsernameNotFoundException(org.springframework.security.core.userdetails.UsernameNotFoundException) OnlineTicket(org.maxkey.authn.online.OnlineTicket) GrantedAuthority(org.springframework.security.core.GrantedAuthority) SigninPrincipal(org.maxkey.authn.SigninPrincipal) UserInfo(org.maxkey.entity.UserInfo)

Example 3 with SigninPrincipal

use of org.maxkey.authn.SigninPrincipal in project MaxKey by dromara.

the class AssertionEndpoint method assertion.

@RequestMapping(value = "/authz/saml20/assertion")
public ModelAndView assertion(HttpServletRequest request, HttpServletResponse response) throws Exception {
    logger.debug("saml20 assertion start.");
    bindingAdapter = (BindingAdapter) request.getSession().getAttribute(WebConstants.AUTHORIZE_SIGN_ON_APP_SAMLV20_ADAPTER);
    logger.debug("saml20 assertion get session samlv20Adapter " + bindingAdapter);
    AppsSAML20Details saml20Details = bindingAdapter.getSaml20Details();
    logger.debug("saml20Details " + saml20Details.getExtendAttr());
    AuthnRequestInfo authnRequestInfo = bindingAdapter.getAuthnRequestInfo();
    if (authnRequestInfo == null) {
        logger.warn("Could not find AuthnRequest on the request.  Responding with SC_FORBIDDEN.");
        throw new Exception();
    }
    logger.debug("AuthnRequestInfo: {}", authnRequestInfo);
    HashMap<String, String> attributeMap = new HashMap<String, String>();
    attributeMap.put(WebConstants.ONLINE_TICKET_NAME, ((SigninPrincipal) WebContext.getAuthentication().getPrincipal()).getOnlineTicket().getTicketId());
    // saml20Details
    Response authResponse = authnResponseGenerator.generateAuthnResponse(saml20Details, authnRequestInfo, attributeMap, bindingAdapter);
    Endpoint endpoint = endpointGenerator.generateEndpoint(saml20Details.getSpAcsUrl());
    request.getSession().removeAttribute(AuthnRequestInfo.class.getName());
    // request issuer...
    try {
        bindingAdapter.sendSAMLMessage(authResponse, endpoint, request, response);
    } catch (MessageEncodingException mee) {
        logger.error("Exception encoding SAML message", mee);
        throw new Exception(mee);
    }
    return null;
}
Also used : HttpServletResponse(javax.servlet.http.HttpServletResponse) Response(org.opensaml.saml2.core.Response) AppsSAML20Details(org.maxkey.entity.apps.AppsSAML20Details) Endpoint(org.opensaml.saml2.metadata.Endpoint) HashMap(java.util.HashMap) AuthnRequestInfo(org.maxkey.authz.saml.common.AuthnRequestInfo) SigninPrincipal(org.maxkey.authn.SigninPrincipal) MessageEncodingException(org.opensaml.ws.message.encoder.MessageEncodingException) MessageEncodingException(org.opensaml.ws.message.encoder.MessageEncodingException) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 4 with SigninPrincipal

use of org.maxkey.authn.SigninPrincipal in project MaxKey by dromara.

the class Cas10AuthorizeEndpoint method validate.

/**
 * @param request
 * @param response
 * @param ticket
 * @param service
 * @param renew
 * @return
 *
 *2.4. /validate [CAS 1.0]
 */validate checks the validity of a service ticket. /validate is part of the CAS 1.0 protocol and thus does not handle proxy authentication. CAS MUST respond with a ticket validation failure response when a proxy ticket is passed to /validate.
 *
 *2.4.1. parameters
 *The following HTTP request parameters MAY be specified to /validate. They are case sensitive and MUST all be handled by /validate.
 *
 *service [REQUIRED] - the identifier of the service for which the ticket was issued, as discussed in Section 2.2.1. As a HTTP request parameter, the service value MUST be URL-encoded as described in Section 2.2 of RFC 1738 [4].
 *
 *Note: It is STRONGLY RECOMMENDED that all service urls be filtered via the service management tool, such that only authorized and known client applications would be able to use the CAS server. Leaving the service management tool open to allow lenient access to all applications will potentially increase the risk of service attacks and other security vulnerabilities. Furthermore, it is RECOMMENDED that only secure protocols such as https be allowed for client applications for further strengthen the authenticating client.
 *
 *ticket [REQUIRED] - the service ticket issued by /login. Service tickets are described in Section 3.1.
 *
 *renew [OPTIONAL] - if this parameter is set, ticket validation will only succeed if the service ticket was issued from the presentation of the user��s primary credentials. It will fail if the ticket was issued from a single sign-on session.
 *
 *2.4.2. response
 */validate will return one of the following two responses:
 *			On ticket validation success:
 *			yes<LF>
 *			username<LF>
 *
 *			On ticket validation failure:
 *			no<LF>
 *			<LF>
 */
@Operation(summary = "CAS 1.0 ticket验证接口", description = "通过ticket获取当前登录用户信息", method = "POST")
@RequestMapping(CasConstants.ENDPOINT.ENDPOINT_VALIDATE)
@ResponseBody
public String validate(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = CasConstants.PARAMETER.TICKET) String ticket, @RequestParam(value = CasConstants.PARAMETER.SERVICE) String service, @RequestParam(value = CasConstants.PARAMETER.RENEW, required = false) String renew) {
    _logger.debug("serviceValidate " + " ticket " + ticket + " , service " + service + " , renew " + renew);
    Ticket storedTicket = null;
    try {
        storedTicket = ticketServices.consumeTicket(ticket);
    } catch (Exception e) {
        _logger.error("consume Ticket error ", e);
    }
    if (storedTicket != null) {
        String principal = ((SigninPrincipal) storedTicket.getAuthentication().getPrincipal()).getUsername();
        _logger.debug("principal " + principal);
        return new Service10ResponseBuilder().success().setUser(principal).serviceResponseBuilder();
    } else {
        _logger.debug("Ticket not found .");
        return new Service10ResponseBuilder().failure().serviceResponseBuilder();
    }
}
Also used : Ticket(org.maxkey.authz.cas.endpoint.ticket.Ticket) Service10ResponseBuilder(org.maxkey.authz.cas.endpoint.response.Service10ResponseBuilder) SigninPrincipal(org.maxkey.authn.SigninPrincipal) Operation(io.swagger.v3.oas.annotations.Operation) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) ResponseBody(org.springframework.web.bind.annotation.ResponseBody)

Example 5 with SigninPrincipal

use of org.maxkey.authn.SigninPrincipal in project MaxKey by dromara.

the class Cas20AuthorizeEndpoint method serviceValidate.

/**
 * @param request
 * @param response
 * @param ticket
 * @param service
 * @param pgtUrl
 * @param renew
 * @param format
 * @return
 *2.5. /serviceValidate [CAS 2.0]
 */serviceValidate checks the validity of a service ticket and returns an XML-fragment response. /serviceValidate MUST also generate and issue proxy-granting tickets when requested. /serviceValidate MUST NOT return a successful authentication if it receives a proxy ticket. It is RECOMMENDED that if /serviceValidate receives a proxy ticket, the error message in the XML response SHOULD explain that validation failed because a proxy ticket was passed to /serviceValidate.
 *
 *2.5.1. parameters
 *The following HTTP request parameters MAY be specified to /serviceValidate. They are case sensitive and MUST all be handled by /serviceValidate.
 *
 *service [REQUIRED] - the identifier of the service for which the ticket was issued, as discussed in Section 2.2.1. As a HTTP request parameter, the service value MUST be URL-encoded as described in Section 2.2 of RFC 1738 [4].
 *
 *Note: It is STRONGLY RECOMMENDED that all service urls be filtered via the service management tool, such that only authorized and known client applications would be able to use the CAS server. Leaving the service management tool open to allow lenient access to all applications will potentially increase the risk of service attacks and other security vulnerabilities. Furthermore, it is RECOMMENDED that only secure protocols such as https be allowed for client applications for further strengthen the authenticating client.
 *
 *ticket [REQUIRED] - the service ticket issued by /login. Service tickets are described in Section 3.1.
 *
 *pgtUrl [OPTIONAL] - the URL of the proxy callback. Discussed in Section 2.5.4. As a HTTP request parameter, the ��pgtUrl�� value MUST be URL-encoded as described in Section 2.2 of RFC 1738 [4].
 *
 *renew [OPTIONAL] - if this parameter is set, ticket validation will only succeed if the service ticket was issued from the presentation of the user��s primary credentials. It will fail if the ticket was issued from a single sign-on session.
 *
 *format [OPTIONAL] - if this parameter is set, ticket validation response MUST be produced based on the parameter value. Supported values are XML and JSON. If this parameter is not set, the default XML format will be used. If the parameter value is not supported by the CAS server, an error code MUST be returned as is described in section 2.5.3.
 *
 *2.5.2. response
 * /serviceValidate will return an XML-formatted CAS serviceResponse as described in the XML schema in Appendix A. Below are example responses:
 *
 *	On ticket validation success:
 *		<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
 *		 <cas:authenticationSuccess>
 *		  <cas:user>username</cas:user>
 *		  <cas:proxyGrantingTicket>PGTIOU-84678-8a9d...</cas:proxyGrantingTicket>
 *		 </cas:authenticationSuccess>
 *		</cas:serviceResponse>
 *
 *		{
 *		  "serviceResponse" : {
 *		    "authenticationSuccess" : {
 *		      "user" : "username",
 *		      "proxyGrantingTicket" : "PGTIOU-84678-8a9d..."
 *		    }
 *		  }
 *		}
 *	On ticket validation failure:
 *		<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
 *		 <cas:authenticationFailure code="INVALID_TICKET">
 *		    Ticket ST-1856339-aA5Yuvrxzpv8Tau1cYQ7 not recognized
 *		  </cas:authenticationFailure>
 *		</cas:serviceResponse>
 *
 *		{
 *		  "serviceResponse" : {
 *		    "authenticationFailure" : {
 *		      "code" : "INVALID_TICKET",
 *		      "description" : "Ticket ST-1856339-aA5Yuvrxzpv8Tau1cYQ7 not recognized"
 *		    }
 *		  }
 *		}
 *
 *	Example response with custom attributes
 *		<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
 *		    <cas:authenticationSuccess>
 *		      <cas:user>username</cas:user>
 *		      <cas:attributes>
 *		        <cas:firstname>John</cas:firstname>
 *		        <cas:lastname>Doe</cas:lastname>
 *		        <cas:title>Mr.</cas:title>
 *		        <cas:email>jdoe@example.org</cas:email>
 *		        <cas:affiliation>staff</cas:affiliation>
 *		        <cas:affiliation>faculty</cas:affiliation>
 *		      </cas:attributes>
 *		      <cas:proxyGrantingTicket>PGTIOU-84678-8a9d...</cas:proxyGrantingTicket>
 *		    </cas:authenticationSuccess>
 *		  </cas:serviceResponse>
 *
 *		 {
 *		  "serviceResponse" : {
 *		    "authenticationSuccess" : {
 *		      "user" : "username",
 *		      "proxyGrantingTicket" : "PGTIOU-84678-8a9d...",
 *		      "proxies" : [ "https://proxy1/pgtUrl", "https://proxy2/pgtUrl" ],
 *		      "attributes" : {
 *		        "firstName" : "John",
 *		        "affiliation" : [ "staff", "faculty" ],
 *		        "title" : "Mr.",
 *		        "email" : "jdoe@example.orgmailto:jdoe@example.org",
 *		        "lastname" : "Doe"
 *		      }
 *		    }
 *		  }
 *		}
 *2.5.3. error codes
 *The following values MAY be used as the ��code�� attribute of authentication failure responses. The following is the minimum set of error codes that all CAS servers MUST implement. Implementations MAY include others.
 *
 *INVALID_REQUEST - not all of the required request parameters were present
 *
 *INVALID_TICKET_SPEC - failure to meet the requirements of validation specification
 *
 *UNAUTHORIZED_SERVICE_PROXY - the service is not authorized to perform proxy authentication
 *
 *INVALID_PROXY_CALLBACK - The proxy callback specified is invalid. The credentials specified for proxy authentication do not meet the security requirements
 *
 *INVALID_TICKET - the ticket provided was not valid, or the ticket did not come from an initial login and renew was set on validation. The body of the \<cas:authenticationFailure\> block of the XML response SHOULD describe the exact details.
 *
 *INVALID_SERVICE - the ticket provided was valid, but the service specified did not match the service associated with the ticket. CAS MUST invalidate the ticket and disallow future validation of that same ticket.
 *
 *INTERNAL_ERROR - an internal error occurred during ticket validation
 *
 *For all error codes, it is RECOMMENDED that CAS provide a more detailed message as the body of the \<cas:authenticationFailure\> block of the XML response.
 */
@Operation(summary = "CAS 2.0 ticket验证接口", description = "通过ticket获取当前登录用户信息", method = "POST")
@RequestMapping(value = CasConstants.ENDPOINT.ENDPOINT_SERVICE_VALIDATE, produces = MediaType.APPLICATION_XML_VALUE)
@ResponseBody
public String serviceValidate(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = CasConstants.PARAMETER.TICKET) String ticket, @RequestParam(value = CasConstants.PARAMETER.SERVICE) String service, @RequestParam(value = CasConstants.PARAMETER.PROXY_CALLBACK_URL, required = false) String pgtUrl, @RequestParam(value = CasConstants.PARAMETER.RENEW, required = false) String renew, @RequestParam(value = CasConstants.PARAMETER.FORMAT, required = false, defaultValue = HttpResponseConstants.FORMAT_TYPE.XML) String format) {
    _logger.debug("serviceValidate " + " ticket " + ticket + " , service " + service + " , pgtUrl " + pgtUrl + " , renew " + renew + " , format " + format);
    Ticket storedTicket = null;
    if (ticket.startsWith(CasConstants.PREFIX.SERVICE_TICKET_PREFIX)) {
        try {
            storedTicket = ticketServices.consumeTicket(ticket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    ServiceResponseBuilder serviceResponseBuilder = new ServiceResponseBuilder();
    if (storedTicket != null) {
        SigninPrincipal authentication = ((SigninPrincipal) storedTicket.getAuthentication().getPrincipal());
        if (StringUtils.isNotBlank(pgtUrl)) {
            ProxyGrantingTicketIOUImpl proxyGrantingTicketIOUImpl = new ProxyGrantingTicketIOUImpl();
            String proxyGrantingTicketIOU = casProxyGrantingTicketServices.createTicket(proxyGrantingTicketIOUImpl);
            ProxyGrantingTicketImpl proxyGrantingTicketImpl = new ProxyGrantingTicketImpl(storedTicket.getAuthentication(), storedTicket.getCasDetails());
            String proxyGrantingTicket = casProxyGrantingTicketServices.createTicket(proxyGrantingTicketImpl);
            serviceResponseBuilder.success().setTicket(proxyGrantingTicketIOU);
            serviceResponseBuilder.success().setProxy(pgtUrl);
            httpRequestAdapter.post(pgtUrl + "?pgtId=" + proxyGrantingTicket + "&pgtIou=" + proxyGrantingTicketIOU, null);
        }
        if (ConstsBoolean.isTrue(storedTicket.getCasDetails().getIsAdapter())) {
            Object samlAdapter = Instance.newInstance(storedTicket.getCasDetails().getAdapter());
            try {
                BeanUtils.setProperty(samlAdapter, "serviceResponseBuilder", serviceResponseBuilder);
            } catch (IllegalAccessException | InvocationTargetException e) {
                _logger.error("setProperty error . ", e);
            }
            UserInfo userInfo = (UserInfo) userInfoService.findByUsername(authentication.getUsername());
            AbstractAuthorizeAdapter adapter = (AbstractAuthorizeAdapter) samlAdapter;
            adapter.setAuthentication(authentication);
            adapter.setUserInfo(userInfo);
            adapter.setApp(storedTicket.getCasDetails());
            adapter.generateInfo();
        }
    } else {
        serviceResponseBuilder.failure().setCode(CasConstants.ERROR_CODE.INVALID_TICKET).setDescription("Ticket " + ticket + " not recognized");
    }
    return serviceResponseBuilder.serviceResponseBuilder();
}
Also used : AbstractAuthorizeAdapter(org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter) Ticket(org.maxkey.authz.cas.endpoint.ticket.Ticket) ProxyGrantingTicketIOUImpl(org.maxkey.authz.cas.endpoint.ticket.ProxyGrantingTicketIOUImpl) UserInfo(org.maxkey.entity.UserInfo) ServiceResponseBuilder(org.maxkey.authz.cas.endpoint.response.ServiceResponseBuilder) ProxyServiceResponseBuilder(org.maxkey.authz.cas.endpoint.response.ProxyServiceResponseBuilder) InvocationTargetException(java.lang.reflect.InvocationTargetException) InvocationTargetException(java.lang.reflect.InvocationTargetException) SigninPrincipal(org.maxkey.authn.SigninPrincipal) ProxyGrantingTicketImpl(org.maxkey.authz.cas.endpoint.ticket.ProxyGrantingTicketImpl) Operation(io.swagger.v3.oas.annotations.Operation) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) ResponseBody(org.springframework.web.bind.annotation.ResponseBody)

Aggregations

SigninPrincipal (org.maxkey.authn.SigninPrincipal)10 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)7 Operation (io.swagger.v3.oas.annotations.Operation)5 UserInfo (org.maxkey.entity.UserInfo)5 Ticket (org.maxkey.authz.cas.endpoint.ticket.Ticket)4 ResponseBody (org.springframework.web.bind.annotation.ResponseBody)4 InvocationTargetException (java.lang.reflect.InvocationTargetException)3 ProxyServiceResponseBuilder (org.maxkey.authz.cas.endpoint.response.ProxyServiceResponseBuilder)3 ServiceResponseBuilder (org.maxkey.authz.cas.endpoint.response.ServiceResponseBuilder)3 AbstractAuthorizeAdapter (org.maxkey.authz.endpoint.adapter.AbstractAuthorizeAdapter)3 HashMap (java.util.HashMap)2 HttpServletResponse (javax.servlet.http.HttpServletResponse)2 ProxyGrantingTicketIOUImpl (org.maxkey.authz.cas.endpoint.ticket.ProxyGrantingTicketIOUImpl)2 ProxyGrantingTicketImpl (org.maxkey.authz.cas.endpoint.ticket.ProxyGrantingTicketImpl)2 OAuth2Authentication (org.maxkey.authz.oauth2.provider.OAuth2Authentication)2 Apps (org.maxkey.entity.apps.Apps)2 ClientDetails (org.maxkey.entity.apps.oauth2.provider.ClientDetails)2 Authentication (org.springframework.security.core.Authentication)2 JOSEException (com.nimbusds.jose.JOSEException)1 JWEHeader (com.nimbusds.jose.JWEHeader)1