SslClientAuth.C 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright (C) 2012 Emweb bvba, Kessel-Lo, Belgium.
  3. *
  4. * See the LICENSE file for terms of use.
  5. */
  6. #include <Wt/WApplication>
  7. #include <Wt/WContainerWidget>
  8. #include <Wt/WServer>
  9. #include <Wt/WEnvironment>
  10. #include <Wt/WSslInfo>
  11. #include <Wt/WText>
  12. #include "Wt/Utils"
  13. #include <Wt/Auth/AuthModel>
  14. #include <Wt/Auth/AuthWidget>
  15. #include <Wt/Auth/PasswordService>
  16. #include <Wt/Auth/Identity>
  17. #include <Wt/Auth/AbstractUserDatabase>
  18. #include "model/Session.h"
  19. namespace {
  20. Wt::Auth::Identity createIdentity(const Wt::WSslInfo* sslInfo)
  21. {
  22. std::string name;
  23. std::vector<Wt::WSslCertificate::DnAttribute> clientSubjectDn
  24. = sslInfo->clientCertificate().subjectDn();
  25. for (unsigned i = 0; i < clientSubjectDn.size(); ++i) {
  26. if (clientSubjectDn[i].name() == Wt::WSslCertificate::CommonName) {
  27. name = clientSubjectDn[i].value();
  28. break;
  29. }
  30. }
  31. std::string der = sslInfo->clientCertificate().toDer();
  32. return Wt::Auth::Identity("CLIENT_SSL",
  33. Wt::Utils::hexEncode(Wt::Utils::sha1(der)),
  34. name,
  35. "",
  36. false);
  37. }
  38. }
  39. class AuthApplication : public Wt::WApplication
  40. {
  41. public:
  42. AuthApplication(const Wt::WEnvironment& env)
  43. : Wt::WApplication(env),
  44. session_(appRoot() + "auth.db")
  45. {
  46. session_.login().changed().connect(this, &AuthApplication::authEvent);
  47. useStyleSheet("css/style.css");
  48. Wt::Auth::AuthWidget *authWidget
  49. = new Wt::Auth::AuthWidget(Session::auth(), session_.users(),
  50. session_.login());
  51. authWidget->setRegistrationEnabled(true);
  52. Wt::WSslInfo *sslInfo = env.sslInfo();
  53. if (sslInfo) {
  54. Wt::Auth::Identity id = createIdentity(sslInfo);
  55. Wt::Auth::User u = session_.users().findWithIdentity(id.provider(),
  56. id.id());
  57. if (!u.isValid())
  58. authWidget->registerNewUser(id);
  59. else
  60. session_.login().login(u, Wt::Auth::WeakLogin);
  61. root()->addWidget(authWidget);
  62. } else {
  63. new Wt::WText("Not an SSL session, or no client certificate available. "
  64. "Please read the readme file in examples/feature/client-ssl-auth "
  65. "for more info.",
  66. root());
  67. quit();
  68. }
  69. }
  70. void authEvent() {
  71. if (session_.login().loggedIn())
  72. Wt::log("notice") << "User " << session_.login().user().id()
  73. << " logged in.";
  74. else {
  75. Wt::log("notice") << "User logged out.";
  76. root()->clear();
  77. new Wt::WText("You are logged out", root());
  78. quit();
  79. }
  80. }
  81. private:
  82. Session session_;
  83. };
  84. Wt::WApplication *createApplication(const Wt::WEnvironment& env)
  85. {
  86. return new AuthApplication(env);
  87. }
  88. int main(int argc, char **argv)
  89. {
  90. try {
  91. Wt::WServer server(argc, argv, WTHTTP_CONFIGURATION);
  92. server.addEntryPoint(Wt::Application, createApplication);
  93. Session::configureAuth();
  94. server.run();
  95. } catch (Wt::WServer::Exception& e) {
  96. std::cerr << e.what() << std::endl;
  97. } catch (std::exception &e) {
  98. std::cerr << "exception: " << e.what() << std::endl;
  99. }
  100. }