Documentation ¶
Overview ¶
Package cas implements a CAS client.
CAS is a protocol which provides authentication and authorisation for securing typically HTTP based services.
References:
[PROTOCOL]: http://jasig.github.io/cas/4.0.x/protocol/CAS-Protocol.html
Example ¶
package main import ( "bytes" "flag" "fmt" "html/template" "net/http" "net/url" "github.com/golang/glog" ) type myHandler struct{} var MyHandler = &myHandler{} var casURL string func init() { flag.StringVar(&casURL, "url", "", "CAS server URL") } func main() { Example() } func main() { flag.Parse() if casURL == "" { flag.Usage() return } glog.Info("Starting up") m := http.NewServeMux() m.Handle("/", MyHandler) url, _ := url.Parse(casURL) client := NewClient(&Options{ URL: url, }) server := &http.Server{ Addr: ":8080", Handler: client.Handle(m), } if err := server.ListenAndServe(); err != nil { glog.Infof("Error from HTTP Server: %v", err) } glog.Info("Shutting down") } type templateBinding struct { Username string Attributes UserAttributes } func (h *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if !IsAuthenticated(r) { RedirectToLogin(w, r) return } if r.URL.Path == "/logout" { RedirectToLogout(w, r) return } w.Header().Add("Content-Type", "text/html") tmpl, err := template.New("index.html").Parse(index_html) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, error_500, err) return } binding := &templateBinding{ Username: Username(r), Attributes: Attributes(r), } html := new(bytes.Buffer) if err := tmpl.Execute(html, binding); err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, error_500, err) return } html.WriteTo(w) } const index_html = `<!DOCTYPE html> <html> <head> <title>Welcome {{.Username}}</title> </head> <body> <h1>Welcome {{.Username}} <a href="/logout">Logout</a></h1> <p>Your attributes are:</p> <ul>{{range $key, $values := .Attributes}} <li>{{$len := len $values}}{{$key}}:{{if gt $len 1}} <ul>{{range $values}} <li>{{.}}</li>{{end}} </ul> {{else}} {{index $values 0}}{{end}}</li>{{end}} </ul> </body> </html> ` const error_500 = `<!DOCTYPE html> <html> <head> <title>Error 500</title> </head> <body> <h1>Error 500</h1> <p>%v</p> </body> </html> `
Output:
Index ¶
- Constants
- Variables
- func AuthenticationDate(r *http.Request) time.Time
- func IsAuthenticated(r *http.Request) bool
- func IsNewLogin(r *http.Request) bool
- func IsRememberedLogin(r *http.Request) bool
- func MemberOf(r *http.Request) []string
- func RedirectToLogin(w http.ResponseWriter, r *http.Request)
- func RedirectToLogout(w http.ResponseWriter, r *http.Request)
- func Username(r *http.Request) string
- type AuthenticationError
- type AuthenticationResponse
- type Client
- func (c *Client) Handle(h http.Handler) http.Handler
- func (c *Client) HandleFunc(h func(http.ResponseWriter, *http.Request)) http.Handler
- func (c *Client) Handler(h http.Handler) http.Handler
- func (c *Client) LoginUrlForRequest(r *http.Request) (string, error)
- func (c *Client) LogoutUrlForRequest(r *http.Request) (string, error)
- func (c *Client) RedirectToLogin(w http.ResponseWriter, r *http.Request)
- func (c *Client) RedirectToLogout(w http.ResponseWriter, r *http.Request)
- func (c *Client) ServiceValidateUrlForRequest(ticket string, r *http.Request) (string, error)
- func (c *Client) ValidateUrlForRequest(ticket string, r *http.Request) (string, error)
- type DefaultURLScheme
- func (scheme *DefaultURLScheme) Login() (*url.URL, error)
- func (scheme *DefaultURLScheme) Logout() (*url.URL, error)
- func (scheme *DefaultURLScheme) RestGrantingTicket() (*url.URL, error)
- func (scheme *DefaultURLScheme) RestLogout(tgt string) (*url.URL, error)
- func (scheme *DefaultURLScheme) RestServiceTicket(tgt string) (*url.URL, error)
- func (scheme *DefaultURLScheme) ServiceValidate() (*url.URL, error)
- func (scheme *DefaultURLScheme) Validate() (*url.URL, error)
- type MemoryStore
- type Options
- type RestClient
- func (c *RestClient) Handle(h http.Handler) http.Handler
- func (c *RestClient) HandleFunc(h func(http.ResponseWriter, *http.Request)) http.Handler
- func (c *RestClient) Logout(tgt TicketGrantingTicket) error
- func (c *RestClient) RequestGrantingTicket(username string, password string) (TicketGrantingTicket, error)
- func (c *RestClient) RequestServiceTicket(tgt TicketGrantingTicket) (ServiceTicket, error)
- func (c *RestClient) ValidateServiceTicket(st ServiceTicket) (*AuthenticationResponse, error)
- type RestOptions
- type ServiceTicket
- type ServiceTicketValidator
- func (validator *ServiceTicketValidator) ServiceValidateUrl(serviceUrl *url.URL, ticket string) (string, error)
- func (validator *ServiceTicketValidator) ValidateTicket(serviceUrl *url.URL, ticket string) (*AuthenticationResponse, error)
- func (validator *ServiceTicketValidator) ValidateUrl(serviceUrl *url.URL, ticket string) (string, error)
- type SessionStore
- type TicketGrantingTicket
- type TicketStore
- type URLScheme
- type UserAttributes
Examples ¶
Constants ¶
const ( INVALID_REQUEST = "INVALID_REQUEST" INVALID_TICKET_SPEC = "INVALID_TICKET_SPEC" UNAUTHORIZED_SERVICE = "UNAUTHORIZED_SERVICE" UNAUTHORIZED_SERVICE_PROXY = "UNAUTHORIZED_SERVICE_PROXY" INVALID_PROXY_CALLBACK = "INVALID_PROXY_CALLBACK" INVALID_TICKET = "INVALID_TICKET" INVALID_SERVICE = "INVALID_SERVICE" INTERNAL_ERROR = "INTERNAL_ERROR" )
AuthenticationError Code values
Variables ¶
var ( // Given Ticket is not associated with an AuthenticationResponse ErrInvalidTicket = errors.New("cas: ticket store: invalid ticket") )
TicketStore errors
Functions ¶
func AuthenticationDate ¶
AuthenticationDate returns the date and time that authentication was performed.
This may return time.IsZero if Authentication Date information is not included in the CAS service validation response. This will be the case for CAS 2.0 protocol servers.
func IsAuthenticated ¶
IsAuthenticated indicates whether the request has been authenticated with CAS.
Example ¶
u, _ := url.Parse("https://cas.example.com") c := NewClient(&Options{ URL: u, }) h := c.HandleFunc(func(w http.ResponseWriter, r *http.Request) { if !IsAuthenticated(r) { RedirectToLogout(w, r) } fmt.Fprintf(w, "Hello World\n") }) err := http.ListenAndServe(":8080", h) if err != nil { log.Fatal("ListenAndServe: ", err) }
Output:
func IsNewLogin ¶
IsNewLogin indicates whether the CAS service ticket was granted following a new authentication.
This may incorrectly return false if Is New Login information is not included in the CAS service validation response. This will be the case for CAS 2.0 protocol servers.
func IsRememberedLogin ¶
IsRememberedLogin indicates whether the CAS service ticket was granted by the presence of a long term authentication token.
This may incorrectly return false if Remembered Login information is not included in the CAS service validation response. This will be the case for CAS 2.0 protocol servers.
func RedirectToLogin ¶
func RedirectToLogin(w http.ResponseWriter, r *http.Request)
RedirectToLogin allows CAS protected handlers to redirect a request to the CAS login page.
Example ¶
u, _ := url.Parse("https://cas.example.com") c := NewClient(&Options{ URL: u, }) h := c.HandleFunc(func(w http.ResponseWriter, r *http.Request) { RedirectToLogin(w, r) }) err := http.ListenAndServe(":8080", h) if err != nil { log.Fatal("ListenAndServe: ", err) }
Output:
func RedirectToLogout ¶
func RedirectToLogout(w http.ResponseWriter, r *http.Request)
RedirectToLogout allows CAS protected handlers to redirect a request to the CAS logout page.
Example ¶
u, _ := url.Parse("https://cas.example.com") c := NewClient(&Options{ URL: u, }) h := c.HandleFunc(func(w http.ResponseWriter, r *http.Request) { RedirectToLogout(w, r) }) err := http.ListenAndServe(":8080", h) if err != nil { log.Fatal("ListenAndServe: ", err) }
Output:
func Username ¶
Username returns the authenticated users username
Example ¶
u, _ := url.Parse("https://cas.example.com") c := NewClient(&Options{ URL: u, }) h := c.HandleFunc(func(w http.ResponseWriter, r *http.Request) { if !IsAuthenticated(r) { RedirectToLogout(w, r) } fmt.Fprintf(w, "Hello %s\n", Username(r)) }) err := http.ListenAndServe(":8080", h) if err != nil { log.Fatal("ListenAndServe: ", err) }
Output:
Types ¶
type AuthenticationError ¶
AuthenticationError represents a CAS AuthenticationFailure response
func (AuthenticationError) AuthenticationError ¶
func (e AuthenticationError) AuthenticationError() bool
AuthenticationError provides a differentiator for casting.
func (AuthenticationError) Error ¶
func (e AuthenticationError) Error() string
Error returns the AuthenticationError as a string
type AuthenticationResponse ¶
type AuthenticationResponse struct { User string // Users login name ProxyGrantingTicket string // Proxy Granting Ticket Proxies []string // List of proxies AuthenticationDate time.Time // Time at which authentication was performed IsNewLogin bool // Whether new authentication was used to grant the service ticket IsRememberedLogin bool // Whether a long term token was used to grant the service ticket MemberOf []string // List of groups which the user is a member of Attributes UserAttributes // Additional information about the user }
AuthenticationResponse captures authenticated user information
func ParseServiceResponse ¶
func ParseServiceResponse(data []byte) (*AuthenticationResponse, error)
ParseServiceResponse returns a successful response or an error
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client implements the main protocol
func (*Client) HandleFunc ¶
HandleFunc wraps a function to provide CAS authentication for the handler function.
func (*Client) Handler ¶
Handler returns a standard http.HandlerFunc, which will check the authenticated status (redirect user go login if needed) If the user pass the authenticated check, it will call the h's ServeHTTP method
func (*Client) LoginUrlForRequest ¶
LoginUrlForRequest determines the CAS login URL for the http.Request.
func (*Client) LogoutUrlForRequest ¶
LogoutUrlForRequest determines the CAS logout URL for the http.Request.
func (*Client) RedirectToLogin ¶
func (c *Client) RedirectToLogin(w http.ResponseWriter, r *http.Request)
RedirectToLogout replies to the request with a redirect URL to authenticate with CAS.
func (*Client) RedirectToLogout ¶
func (c *Client) RedirectToLogout(w http.ResponseWriter, r *http.Request)
RedirectToLogout replies to the request with a redirect URL to log out of CAS.
func (*Client) ServiceValidateUrlForRequest ¶
ServiceValidateUrlForRequest determines the CAS serviceValidate URL for the ticket and http.Request.
type DefaultURLScheme ¶
type DefaultURLScheme struct { LoginPath string LogoutPath string ValidatePath string ServiceValidatePath string RestEndpoint string // contains filtered or unexported fields }
DefaultURLScheme is a configurable URLScheme. Use NewDefaultURLScheme to create DefaultURLScheme with the default cas urls.
func NewDefaultURLScheme ¶
func NewDefaultURLScheme(base *url.URL) *DefaultURLScheme
NewDefaultURLScheme creates a URLScheme which uses the cas default urls
func (*DefaultURLScheme) Login ¶
func (scheme *DefaultURLScheme) Login() (*url.URL, error)
Login returns the url for the cas login page
func (*DefaultURLScheme) Logout ¶
func (scheme *DefaultURLScheme) Logout() (*url.URL, error)
Logout returns the url for the cas logut page
func (*DefaultURLScheme) RestGrantingTicket ¶
func (scheme *DefaultURLScheme) RestGrantingTicket() (*url.URL, error)
RestGrantingTicket returns the url for requesting an granting ticket via rest api
func (*DefaultURLScheme) RestLogout ¶
func (scheme *DefaultURLScheme) RestLogout(tgt string) (*url.URL, error)
RestLogout returns the url for destroying an granting ticket via rest api
func (*DefaultURLScheme) RestServiceTicket ¶
func (scheme *DefaultURLScheme) RestServiceTicket(tgt string) (*url.URL, error)
RestServiceTicket returns the url for requesting an service ticket via rest api
func (*DefaultURLScheme) ServiceValidate ¶
func (scheme *DefaultURLScheme) ServiceValidate() (*url.URL, error)
ServiceValidate returns the url for the service validation endpoint
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore implements the TicketStore interface storing ticket data in memory.
func (*MemoryStore) Delete ¶
func (s *MemoryStore) Delete(id string) error
Delete removes the AuthenticationResponse for a ticket
func (*MemoryStore) Read ¶
func (s *MemoryStore) Read(id string) (*AuthenticationResponse, error)
Read returns the AuthenticationResponse for a ticket
func (*MemoryStore) Write ¶
func (s *MemoryStore) Write(id string, ticket *AuthenticationResponse) error
Write stores the AuthenticationResponse for a ticket
type Options ¶
type Options struct { URL *url.URL // URL to the CAS service Store TicketStore // Custom TicketStore, if nil a MemoryStore will be used Client *http.Client // Custom http client to allow options for http connections SendService bool // Custom sendService to determine whether you need to send service param URLScheme URLScheme // Custom url scheme, can be used to modify the request urls for the client Cookie *http.Cookie // http.Cookie options, uses Path, Domain, MaxAge, HttpOnly, & Secure SessionStore SessionStore }
Client configuration options
type RestClient ¶
type RestClient struct {
// contains filtered or unexported fields
}
RestClient uses the rest protocol provided by cas
func NewRestClient ¶
func NewRestClient(options *RestOptions) *RestClient
NewRestClient creates a new client for the cas rest protocol with the provided options
func (*RestClient) Handle ¶
func (c *RestClient) Handle(h http.Handler) http.Handler
Handle wraps a http.Handler to provide CAS Rest authentication for the handler.
func (*RestClient) HandleFunc ¶
func (c *RestClient) HandleFunc(h func(http.ResponseWriter, *http.Request)) http.Handler
HandleFunc wraps a function to provide CAS Rest authentication for the handler function.
func (*RestClient) Logout ¶
func (c *RestClient) Logout(tgt TicketGrantingTicket) error
Logout destroys the given granting ticket
func (*RestClient) RequestGrantingTicket ¶
func (c *RestClient) RequestGrantingTicket(username string, password string) (TicketGrantingTicket, error)
RequestGrantingTicket returns a new TGT, if the username and password authentication was successful
func (*RestClient) RequestServiceTicket ¶
func (c *RestClient) RequestServiceTicket(tgt TicketGrantingTicket) (ServiceTicket, error)
RequestServiceTicket requests a service ticket with the TGT for the configured service url
func (*RestClient) ValidateServiceTicket ¶
func (c *RestClient) ValidateServiceTicket(st ServiceTicket) (*AuthenticationResponse, error)
ValidateServiceTicket validates the service ticket and returns an AuthenticationResponse
type RestOptions ¶
type RestOptions struct { CasURL *url.URL ServiceURL *url.URL Client *http.Client URLScheme URLScheme }
RestOptions provide options for the RestClient
type ServiceTicket ¶
type ServiceTicket string
ServiceTicket stands for the access granted by the CAS server to an application for a specific user, also known as ST
type ServiceTicketValidator ¶
type ServiceTicketValidator struct {
// contains filtered or unexported fields
}
ServiceTicketValidator is responsible for the validation of a service ticket
func NewServiceTicketValidator ¶
func NewServiceTicketValidator(client *http.Client, casUrl *url.URL) *ServiceTicketValidator
func (*ServiceTicketValidator) ServiceValidateUrl ¶
func (validator *ServiceTicketValidator) ServiceValidateUrl(serviceUrl *url.URL, ticket string) (string, error)
ServiceValidateUrl creates the service validation url for the cas >= 2 protocol. TODO the function is only exposed, because of the clients ServiceValidateUrl function
func (*ServiceTicketValidator) ValidateTicket ¶
func (validator *ServiceTicketValidator) ValidateTicket(serviceUrl *url.URL, ticket string) (*AuthenticationResponse, error)
ValidateTicket validates the service ticket for the given server. The method will try to use the service validate endpoint of the cas >= 2 protocol, if the service validate endpoint not available, the function will use the cas 1 validate endpoint.
func (*ServiceTicketValidator) ValidateUrl ¶
func (validator *ServiceTicketValidator) ValidateUrl(serviceUrl *url.URL, ticket string) (string, error)
ValidateUrl creates the validation url for the cas >= 1 protocol. TODO the function is only exposed, because of the clients ValidateUrl function
type SessionStore ¶
type SessionStore interface { // Get the ticket with the session id Get(sessionID string) (string, bool) // Set the session with a ticket Set(sessionID, ticket string) error // Delete the session Delete(sessionID string) error }
SessionStore store the session's ticket SessionID is retrived from cookies
func NewMemorySessionStore ¶
func NewMemorySessionStore() SessionStore
NewMemorySessionStore create a default SessionStore that uses memory
type TicketGrantingTicket ¶
type TicketGrantingTicket string
TicketGrantingTicket represents a SSO session for a user, also known as TGT
type TicketStore ¶
type TicketStore interface { // Read returns the AuthenticationResponse data associated with a ticket identifier. Read(id string) (*AuthenticationResponse, error) // Write stores the AuthenticationResponse data received from a ticket validation. Write(id string, ticket *AuthenticationResponse) error // Delete removes the AuthenticationResponse data associated with a ticket identifier. Delete(id string) error // Clear removes all of the AuthenticationResponse data from the store. Clear() error }
TicketStore provides an interface for storing and retrieving service ticket data.
type URLScheme ¶
type URLScheme interface { Login() (*url.URL, error) Logout() (*url.URL, error) Validate() (*url.URL, error) ServiceValidate() (*url.URL, error) RestGrantingTicket() (*url.URL, error) RestServiceTicket(tgt string) (*url.URL, error) RestLogout(tgt string) (*url.URL, error) }
URLScheme creates the url which are required to handle the cas protocol.
type UserAttributes ¶
UserAttributes represents additional data about the user
func Attributes ¶
func Attributes(r *http.Request) UserAttributes
Attributes returns the authenticated users attributes.
func (UserAttributes) Add ¶
func (a UserAttributes) Add(name, value string)
Add appends a new attribute.
func (UserAttributes) Get ¶
func (a UserAttributes) Get(name string) string
Get retrieves an attribute by name.
Attributes are stored in arrays. Get will only return the first element.